I haven’t posted for a while.
Recently I faced the issue of finding a standard function module or class that converts a TIMESTAMP value to an ISO-8601 long text that reflects the time-zone and does not use always UTC.
I found class CL_XLF_DATE_TIME that does the UTC conversion but not reflecting the timezones.
I had to write my own method doing what I need based on CL_XLF_DATE_TIME~CREATE:
Method interface: IV_TIMESTAMP TYPE TIMESTAMP IV_TZONE TYPE SY-ZONLO DEFAULT SY-ZONLO Uservalue( RV_ISO_STRING ) TYPE STRING METHOD timestamp_to_iso_string. DATA: lv_ts TYPE string, lv_len TYPE i, lv_lchar TYPE c, lv_zone_s TYPE string, lv_zonerule TYPE tznzonerul, ls_ttzr TYPE ttzr. lv_ts = iv_timestamp. lv_len = strlen( lv_ts ). lv_lchar = substring( val = lv_ts off = lv_len - 1 len = 1 ). IF lv_lchar = '-'. rv_iso_string = `-`. lv_ts = substring( val = lv_ts off = 0 len = lv_len - 1 ). ELSEIF lv_lchar = space. CLEAR rv_iso_string. lv_ts = substring( val = lv_ts off = 0 len = lv_len - 1 ). ENDIF. WHILE strlen( lv_ts ) < 14. lv_ts = `0` && lv_ts. ENDWHILE. lv_zone_s = 'Z'. "Default UTC SELECT SINGLE zonerule FROM ttzz INTO lv_zonerule WHERE tzone = iv_tzone. IF sy-subrc = 0. SELECT SINGLE * FROM ttzr INTO ls_ttzr WHERE zonerule = lv_zonerule. IF sy-subrc = 0. lv_zone_s = ls_ttzr-utcsign && ls_ttzr-utcdiff+0(2) && ':' && ls_ttzr-utcdiff+2(2). ENDIF. ENDIF. rv_iso_string = rv_iso_string && lv_ts+0(4) && `-` && lv_ts+4(2) && `-` && lv_ts+6(2) && `T` && lv_ts+8(2) && `:` && lv_ts+10(2) && `:` && lv_ts+12(2) && lv_zone_s. ENDMETHOD.
Here are some examples:
Date 18/07/2020, Time 22:07:12 in EET timezone is converted to “2020-07-18T20:07:12+02:00”
Date 21/04/2020, Time 18:09:25 in UTC is converted to “2020-04-21T18:09:25Z”. The Z is for the UTC.