Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

ABAP TIMESTAMP is wrongly formatted

MikeB
Contributor
0 Kudos

I have a table with a field of the type TIMESTAMP (DEC15).

The problem is that in the reports and in the SE16 this timestamp is represented in a weird way ("XX.XXX.XXX.XXX.XXX" vs. "YYYY.MM.DD.HH.MM.SS"), e.g. "20.180.805.173.751" instead of "2018.08.05.17:37:51".

My assumption is that the table date field's format has been changed after a table maintenance screen has been generated.

Does anyone know what could be a reason for such mis-formatting in the representation?

1 ACCEPTED SOLUTION

michael_piesche
Active Contributor

Is it a SAP standard or a custom table?

  • Of course you have the option in your own reporting to convert the value by coding e.g. from the Decimal into a String and then into a readable format and present that string in output values (e.g. ALV) instead of the decimal.
  • But in order to always have the Decimal converted into a readable Date/Time value, no matter where the table attribute is used (e.g. SE16N, Selection Screens, etc.), and not have to always develop that logic each time it is used, you will have to change the Conversion Routine of the domain.
  • If it is a SAP standard table, you would have to modify the standard domain, which in most cases will not be an option. But you could also create a view of the standard table and exchange the standard data element of the timestamp attribute with a custom data element that has the 'identical' domain, just with the conversion routine that fullfills your purpose. And instead of using the standard table, you would use your custom view.
  • If it is a custom table, you can easily assign the TIMES conversion routine to a custom domain of your timestamp (or use standard data elements and/or domains that utilize conversion routines like TIMES), or implement your own conversion routine if you have different output requirements (e.g. which timezone other than the time zone of the current user, sy-zonlo, should be used?):

The following screenshot shows on the left when the conversion exit is applied (by default in GUI output), and on the right when it is suppressed by SE16N settings:

This is what the Conversion Exit TIMES for Output looks like:

FUNCTION conversion_exit_times_output.
*"----------------------------------------------------------------------
*"*"Local interface:
*"  IMPORTING
*"     VALUE(INPUT)
*"  EXPORTING
*"     VALUE(OUTPUT)
*"----------------------------------------------------------------------
  DATA:   l_timestmp TYPE tzntstmps,
          l_date TYPE d,
          l_time TYPE t,
          l_input TYPE string,
          l_init_timestmp(14) type n.

  output = input.

  l_input = input.
  CONDENSE l_input.
  IF NOT l_input IS INITIAL
  AND l_input CO '0123456789.'.
    l_timestmp = l_input.
    CONVERT TIME STAMP l_timestmp TIME ZONE sy-zonlo
            INTO DATE l_date TIME l_time.

    if sy-subrc = 0 or l_input = l_init_timestmp.
      WRITE l_date TO output.
      WRITE l_time TO output+12.
    ENDIF.

  ENDIF.

ENDFUNCTION.

Of course you should also implement the Conversion Exit for Input, as it comes really handy when setting timestamps for selection or setting in GUI input fields.

The Conversion Exit TIMES for Input looks like this:

FUNCTION conversion_exit_times_input.
*"----------------------------------------------------------------------
*"*"Local interface:
*"  IMPORTING
*"     VALUE(INPUT)
*"  EXPORTING
*"     VALUE(OUTPUT)
*"----------------------------------------------------------------------

statics: s_init_date(10)    type c,
         s_init_time(8)     type c.

* BW12B PATCH20 CHM20000329
  DATA: l_date LIKE sy-datum,
        l_time LIKE sy-uzeit,
        l_date_c(15) TYPE c,
        l_time_c(15) TYPE c,
        l_init_date  type d,
        l_init_time  type t,
        l_tstamp     LIKE tzonref-tstamps.

  IF input IS INITIAL.
    CLEAR output.
    EXIT.
  ENDIF.

  if s_init_date is initial.
    write l_init_date to s_init_date.
    write l_init_time to s_init_time.
  endif.

  SPLIT input AT space INTO l_date_c l_time_c.
  CONDENSE l_date_c.
  CONDENSE l_time_c.
* BW30B PATCH11 CHM20030218
  IF l_date_c = s_init_date.                           "H1373765 time can be 00:00:00
    CLEAR output.
    EXIT.
  ENDIF.
* BW30B PATCH11 CHM20030218
  CALL FUNCTION 'CONVERT_DATE_INPUT'
    EXPORTING
      input                     = l_date_c
    IMPORTING
      output                    = l_date
    EXCEPTIONS
      plausibility_check_failed = 1
      wrong_format_in_input     = 2.
  IF sy-subrc <> 0.
    IF sy-subrc = 1.
      MESSAGE s070(rsdd) DISPLAY LIKE 'E' WITH l_date_c.
    ELSEIF sy-subrc = 2.
      MESSAGE s071(rsdd) DISPLAY LIKE 'E' WITH l_date_c.
    ENDIF.
    l_date = sy-datum.
  ENDIF.
  IF l_time_c IS INITIAL.
    l_time = sy-uzeit.
  ELSE.
    CALL FUNCTION 'CONVERT_TIME_INPUT'
      EXPORTING
        input                     = l_time_c
      IMPORTING
        output                    = l_time
      EXCEPTIONS
        plausibility_check_failed = 1
        wrong_format_in_input     = 2.
    IF sy-subrc <> 0.
      IF sy-subrc = 1.
        MESSAGE s072(rsdd) DISPLAY LIKE 'E' WITH l_time_c.
      ELSEIF sy-subrc = 2.
        MESSAGE s073(rsdd) DISPLAY LIKE 'E' WITH l_time_c.
      ENDIF.
      CLEAR l_time.
    ENDIF.
  ENDIF.
  CONVERT DATE l_date TIME l_time INTO
     TIME STAMP l_tstamp TIME ZONE sy-zonlo.

  output = l_tstamp.

* BW12B PATCH20 CHM20000329

ENDFUNCTION.
8 REPLIES 8

mateuszadamus
Active Contributor

Hello mikeb.

As you mentioned the field is of the DEC15. This means the value contained in it is recognized as a number, not as a date. Hence a separator after every 3 digits.

Kind regards,
Mateusz

0 Kudos

Thanks, Mateusz.

Yes it makes sense, but at the same time the data element TIMESTAMP is the default one provided by SAP for needs of time stamping.

Is there any way to represent it in a more readable way ("YYYY.MM.DD.HH.MM.SS")?

Hi

I don't think it's possible in SE16.

In your own report you can use the CONVERT keyword.

CONVERT TIME STAMP ts TIME ZONE sy-zonlo
  INTO DATE DATA(date) TIME DATA(time)
  DAYLIGHT SAVING TIME DATA(dst).

Kind regards,
Mateusz

raymond_giuseppi
Active Contributor

If you want a 'timestamp' field to be displayed in a human readable and suitable format, look for other domains related to timestamp but with a conversion exit similar to CITST or TSTPS, but not with a DEC (packed) field. (A must read is blog About Timestamps by horst.keller.)

0 Kudos

It looks like there is a TIMESTAMP domain based on CHAR14 data type, I'll try to apply it.

michael_piesche
Active Contributor

Is it a SAP standard or a custom table?

  • Of course you have the option in your own reporting to convert the value by coding e.g. from the Decimal into a String and then into a readable format and present that string in output values (e.g. ALV) instead of the decimal.
  • But in order to always have the Decimal converted into a readable Date/Time value, no matter where the table attribute is used (e.g. SE16N, Selection Screens, etc.), and not have to always develop that logic each time it is used, you will have to change the Conversion Routine of the domain.
  • If it is a SAP standard table, you would have to modify the standard domain, which in most cases will not be an option. But you could also create a view of the standard table and exchange the standard data element of the timestamp attribute with a custom data element that has the 'identical' domain, just with the conversion routine that fullfills your purpose. And instead of using the standard table, you would use your custom view.
  • If it is a custom table, you can easily assign the TIMES conversion routine to a custom domain of your timestamp (or use standard data elements and/or domains that utilize conversion routines like TIMES), or implement your own conversion routine if you have different output requirements (e.g. which timezone other than the time zone of the current user, sy-zonlo, should be used?):

The following screenshot shows on the left when the conversion exit is applied (by default in GUI output), and on the right when it is suppressed by SE16N settings:

This is what the Conversion Exit TIMES for Output looks like:

FUNCTION conversion_exit_times_output.
*"----------------------------------------------------------------------
*"*"Local interface:
*"  IMPORTING
*"     VALUE(INPUT)
*"  EXPORTING
*"     VALUE(OUTPUT)
*"----------------------------------------------------------------------
  DATA:   l_timestmp TYPE tzntstmps,
          l_date TYPE d,
          l_time TYPE t,
          l_input TYPE string,
          l_init_timestmp(14) type n.

  output = input.

  l_input = input.
  CONDENSE l_input.
  IF NOT l_input IS INITIAL
  AND l_input CO '0123456789.'.
    l_timestmp = l_input.
    CONVERT TIME STAMP l_timestmp TIME ZONE sy-zonlo
            INTO DATE l_date TIME l_time.

    if sy-subrc = 0 or l_input = l_init_timestmp.
      WRITE l_date TO output.
      WRITE l_time TO output+12.
    ENDIF.

  ENDIF.

ENDFUNCTION.

Of course you should also implement the Conversion Exit for Input, as it comes really handy when setting timestamps for selection or setting in GUI input fields.

The Conversion Exit TIMES for Input looks like this:

FUNCTION conversion_exit_times_input.
*"----------------------------------------------------------------------
*"*"Local interface:
*"  IMPORTING
*"     VALUE(INPUT)
*"  EXPORTING
*"     VALUE(OUTPUT)
*"----------------------------------------------------------------------

statics: s_init_date(10)    type c,
         s_init_time(8)     type c.

* BW12B PATCH20 CHM20000329
  DATA: l_date LIKE sy-datum,
        l_time LIKE sy-uzeit,
        l_date_c(15) TYPE c,
        l_time_c(15) TYPE c,
        l_init_date  type d,
        l_init_time  type t,
        l_tstamp     LIKE tzonref-tstamps.

  IF input IS INITIAL.
    CLEAR output.
    EXIT.
  ENDIF.

  if s_init_date is initial.
    write l_init_date to s_init_date.
    write l_init_time to s_init_time.
  endif.

  SPLIT input AT space INTO l_date_c l_time_c.
  CONDENSE l_date_c.
  CONDENSE l_time_c.
* BW30B PATCH11 CHM20030218
  IF l_date_c = s_init_date.                           "H1373765 time can be 00:00:00
    CLEAR output.
    EXIT.
  ENDIF.
* BW30B PATCH11 CHM20030218
  CALL FUNCTION 'CONVERT_DATE_INPUT'
    EXPORTING
      input                     = l_date_c
    IMPORTING
      output                    = l_date
    EXCEPTIONS
      plausibility_check_failed = 1
      wrong_format_in_input     = 2.
  IF sy-subrc <> 0.
    IF sy-subrc = 1.
      MESSAGE s070(rsdd) DISPLAY LIKE 'E' WITH l_date_c.
    ELSEIF sy-subrc = 2.
      MESSAGE s071(rsdd) DISPLAY LIKE 'E' WITH l_date_c.
    ENDIF.
    l_date = sy-datum.
  ENDIF.
  IF l_time_c IS INITIAL.
    l_time = sy-uzeit.
  ELSE.
    CALL FUNCTION 'CONVERT_TIME_INPUT'
      EXPORTING
        input                     = l_time_c
      IMPORTING
        output                    = l_time
      EXCEPTIONS
        plausibility_check_failed = 1
        wrong_format_in_input     = 2.
    IF sy-subrc <> 0.
      IF sy-subrc = 1.
        MESSAGE s072(rsdd) DISPLAY LIKE 'E' WITH l_time_c.
      ELSEIF sy-subrc = 2.
        MESSAGE s073(rsdd) DISPLAY LIKE 'E' WITH l_time_c.
      ENDIF.
      CLEAR l_time.
    ENDIF.
  ENDIF.
  CONVERT DATE l_date TIME l_time INTO
     TIME STAMP l_tstamp TIME ZONE sy-zonlo.

  output = l_tstamp.

* BW12B PATCH20 CHM20000329

ENDFUNCTION.

Thanks for the detailed expalanation.

It's a custom table.

mikeb., so you should be able to easily set the TIMES conversion routine for your custom domain, or use any other of the above mentioned solutions. Let me know if there are any further issues with solving your requirement.