Posted: Mon Feb 25, 2008 1:01 pm Post subject: Convert ISO 8601 Time to ABAP Representation
Code:
report zcen_iso8601 no standard page heading.title
**************************************************
* T R A N S L A T I O N F O R M
*
* F O R I S O 8 6 0 1 T I M E S T A M P S
*
* Version 1.00
* This code allows direct translation of date/time string formatted
* in the notation defined by ISO 8601 into abap date/time format.
*
* It does also almost fully support RFC 3339.
*
* Not supported ISO 8601 formats are:
* - Intervals
* - Periods
* - Some formats with assumed data
* - Fractional parts of seconds
*
* Not supported RFC 3339 formats are:
* - Fractional parts of seconds
*
* This is freeware. Please read the terms of use.
* Written by Urs Rohner, Rohner IT Consulting & Engineering
*
* Contact Author: Urs Rohner
*
*
*
*
*
*references
* [1] W3C Date and Time Formats
* http://www.w3.org/TR/NOTE-datetime
* [2] Summary on International Standard Date and Time Notations
* http://www.cl.cam.ac.uk/~mgk25/iso-time.html
*
*
*comments
*
* Recognized Date Formats:
* Format Pattern Granularity Remark
* ---------- ---------- ----------- -------------------
* yy ++ Y century assumed
* cccc ++++ Y
* -kkk -+++ D year assumed
* yykkk +++++ D century assumed
* yy-mm ++-++ M century assumed
* yyWww ++W++ W century assumed
* yymmdd ++++++ D century assumed
* yy-kkk ++-+++ D century assumed
* yy-Www ++-W++ W century assumed
* yyWwwo ++W+++ D century assumed
* cccckkk +++++++ D
* cccc-mm ++++-++ M
* ccccWww ++++W++ W
* ccccmmdd ++++++++ D
* cccc-kkk ++++-+++ D
* ccccWwwo ++++W+++ D
* cccc-Www ++++-W++ W
* yy-Www-o ++-W++-+ D century assumed
* yy-mm-dd ++-++-++ D century assumed
* cccc-Www-o ++++-W++-+ D
* cccc-mm-dd ++++-++-++ D
* Literals are: '-', 'W'
*
* Recognized Time Formats:
* Format Pattern Granularity Remark
* ---------- ---------- ----------- -------------------
* hh ++ h
* hhii ++++ m
* hhiiss ++++++ s
* hh:ii ++:++ m
* hh:ii:ss ++:++:++ s
* Literals are: ':'
*
* Recognized Timezone Formats:
* Format Pattern Sign Remark
* ---------- ---------- ---------- -------------------
* Z Z 0 UTC
* +tt #+++ +1
* +ttff #+++++ +1
* +tt:ff #+++:++ +1
* -tt -++ -1
* -ttff -++++ -1
* -tt:ff -++:++ -1
* Literals are: 'Z', '-', '#+', ':'
*
* Granularity, ie. degree of Resolution:
* res_ Degree Remark Res
* ---- ---------- --------------------------------------- -------
* 'Y' Year only year given lowest
* 'M' Year Month year plus month given month
* 'W' Year Week year plus week number given week
* 'D' Year Day exact date given, ie. year month day day
* 'h' Hour date plus hour hour
* 'm' Minute date plus hour and minute minute
* 's' Second date and exact time highest
*
*
**********************************************************
types:
" Granularity of probed string
t_granularity(7) type c.
types:
" maximal datr/time representation in ISO 8601
" without fractional part
t_raw(25) type c.
types:
" Intermediate data container
begin of t_vars,
granularity type t_granularity, " pattern granularity
" date related
c(4) type n, _c type c, " 4 digit year
y(2) type n, _y type c, " 2 digit year
k(3) type n, _k type c, " day in year
w(2) type n, _w type c, " week in year
m(2) type n, _m type c, " month
d(2) type n, _d type c, " day
o(1) type n, _o type c, " day in week
" time related
h(2) type n, _h type c, " hour
i(2) type n, _i type c, " minute
s(2) type n, _s type c, " second
" timezone related
sign type i, " sign to zone difference
t(2) type n, _t type c, " difference in hours
f(2) type n, _f type c, " difference in minutes
end of t_vars.
* Method: m_iso2time_patt>
* Convert a iso2time search pattern to an Abap string pattern
define m_iso2time_patt>.
perform m_iso2time_patt using &1 &2 &3.
end-of-definition.
form m_iso2time_patt using
value(ipat_) type t_raw " internal iso2time pattern
apat_ type t_raw " Abap string pattern
res_ type t_granularity. " derived resolution code
data:
_vars(13) type c,
_l type i,
_x type i,
_y type i.
" compute granularity of given pattern
define m_iso2time_patt_res>.
if &1 ca &2.
concatenate res_ &3 into res_.
endif.
concatenate _vars &2 into _vars.
end-of-definition.
" initialize
clear:
apat_,
res_.
" compute patterns granularity and variable identifiers
m_iso2time_patt_res> ipat_:
'cy' 'Y', 'm' 'M', 'w' 'W',
'k' 'D', 'o' 'D', 'd' 'D',
'h' 'h', 'i' 'm', 's' 's',
't' ' ', 'f' ' '.
if not res_ is initial.
" create a pattern
_l = strlen( ipat_ ).
do _l times.
if ipat_+_y(1) ca _vars.
apat_+_x(1) = '+'.
add 1 to _x.
elseif ipat_+_y(1) eq '+'.
apat_+_x(2) = '#+'.
add 2 to _x.
else.
apat_+_x(1) = ipat_+_y(1).
add 1 to _x.
endif.
add 1 to _y.
enddo.
endif.
endform.
form m_iso2time_setvar using
value(raw_) type t_raw " raw date string to test
vars_ type t_vars " variable container
value(pattern_) type t_raw. " pattern to check
data:
_pattern type t_raw,
_l type i,
_x type i,
_c type c,
_last_c type c,
_digit type i,
_n(10) type c.
field-symbols:
<n>.
if vars_ is initial and not raw_ is initial.
" create pattern
m_iso2time_patt> pattern_ _pattern vars_-granularity.
_l = strlen( raw_ ).
if raw_+0(_l) cp _pattern.
" pattern matches, try to fill variables
" loop thru all characters of raw string
do _l times.
" capitalize character in pattern
_c = pattern_+_x(1).
translate _c to upper case.
" now check what the current character represents
if _c eq pattern_+_x(1).
" it's a literal
if pattern_ ca 't'.
" time with UTC offset
case _c.
when '+'. vars_-sign = 1.
when '-'. vars_-sign = -1.
endcase.
elseif _c eq 'Z'.
vars_-sign = 1. " time in UTC
endif.
else.
" it's part of a variable
if raw_+_x(1) co '0123456789'.
" as expected its a digit
if _c ne _last_c.
clear _digit.
endif.
" set digit
concatenate 'VARS_-' _c into _n.
assign (_n) to <n>.
<n>+_digit(1) = raw_+_x(1).
" set set flag
concatenate 'VARS_-_' _c into _n.
assign (_n) to <n>.
<n> = 'X'.
add 1 to _digit.
_last_c = _c.
else.
" error, digit expected
clear vars_.
exit.
endif.
endif.
add 1 to _x.
enddo.
else.
" does not match pattern
clear vars_.
endif.
endif.
endform.
form m_iso2time_date_setvar using
value(raw_) type t_raw " raw date string to test
vars_ type t_vars " variable container
date_ type d. " date
data:
_week type scal-week.
clear:
vars_,
date_.
m_iso2time_setvar> raw_ vars_:
'yy', 'cccc', 'yy-kkk', 'cccc-kkk',
'yy-mm', 'cccc-mm', 'yyWwwo', 'ccccWwwo',
'yyWww', 'ccccWww', 'yy-Www-o', 'cccc-Www-o',
'yy-Www', 'cccc-Www', 'yymmdd', 'ccccmmdd',
'yykkk', 'cccckkk', 'yy-mm-dd', 'cccc-mm-dd',
'-kkk'.
if not vars_ is initial.
" everything okay so far, try to compile date
" Do Year
if not vars_-_c is initial.
" set year
date_+0(4) = vars_-c.
elseif not vars_-_y is initial.
" set year, assume century
date_+2(2) = vars_-y.
if vars_-y gt '21'. " I chose year 2021, SAP has currently
date_+0(2) = '19'. " some problems going beyond that date
else.
date_+0(2) = '20'.
endif.
else.
" not given, set to current year
date_+0(4) = sy-datum+0(4).
endif.
" Do Month
if not vars_-_m is initial.
if vars_-m between 1 and 12.
date_+4(2) = vars_-m.
else.
clear vars_. " month out of range
endif.
endif.
" Do Day
if not vars_-_d is initial.
if vars_-d between 1 and 31.
date_+6(2) = vars_-d.
else.
clear vars_. " day out of range
endif.
endif.
" Do day of year
if not vars_-_k is initial.
if vars_-k between 1 and 365.
date_+4(4) = '0101'.
date_ = date_ + vars_-k - 1.
else.
clear vars_. " day of year out of range
endif.
endif.
if not vars_-_w is initial.
" compute date out of week number
if vars_-w between 1 and 53.
_week+0(4) = date_+0(4).
_week+4(2) = vars_-w.
call function 'WEEK_GET_FIRST_DAY'
exporting
week = _week
importing
date = date_
exceptions
week_invalid = 1
others = 2.
if not sy-subrc is initial.
clear vars_. " invalid week specified
endif.
else.
clear vars_. " week number out of range
endif.
endif.
" add day number to date
if not vars_-_o is initial.
if vars_-o between 1 and 7.
date_ = date_ + vars_-o - 1.
else.
clear vars_. " weekday number out of range
endif.
endif.
if vars_-granularity ca 'D'.
" almost have it
call function 'DATE_CHECK_PLAUSIBILITY'
exporting
date = date_
exceptions
plausibility_check_failed = 1
others = 2.
if not sy-subrc is initial.
clear vars_. " something else wrong with date
endif.
endif.
form m_iso2time_time_setvar using
value(raw_) type t_raw " raw time string to test
vars_ type t_vars " variable container
time_ type t " time
zone_ type i " timezone difference
zone_unknown_ type c " timezone specified as unknown
offset_ type i. " date offset
" compute timezone difference
if not vars_-_t is initial.
if vars_-t between 0 and 12.
zone_ = vars_-t * 60.
else.
clear vars_. " timezone hours out of range
endif.
endif.
if not vars_-_f is initial.
if vars_-f between 0 and 59.
add vars_-f to zone_.
else.
clear vars_. " timezone minutes out of range
endif.
endif.
multiply zone_ by vars_-sign.
if not zone_ between -720 and 720.
clear vars_. " timezone makes no sense
endif.
" special case in RFC3339
" check whether timezone is unknown
if vars_-sign eq -1
and not vars_-_t is initial and vars_-t eq 0
and not vars_-_f is initial and vars_-f eq 0.
zone_unknown_ = 'X'.
endif.
" set time
" first, treat special case midnight
if vars_-granularity ca 's'.
if vars_-h eq 24 and vars_-m eq 0 and vars_-s eq 0.
clear vars_-h.
offset_ = 1.
endif.
endif.
" do hours
if not vars_-_h is initial.
if vars_-h between 0 and 23.
time_+0(2) = vars_-h.
else.
clear vars_. " wrong hour
endif.
endif.
" do minutes
if not vars_-_i is initial.
if vars_-i between 0 and 59.
time_+2(2) = vars_-i.
else.
clear vars_. " wrong minutes
endif.
endif.
" do seconds
if not vars_-_s is initial.
if vars_-s between 0 and 59.
time_+4(2) = vars_-s.
elseif vars_-s eq 60.
" check whether we have a leap second
_time = vars_-i + vars_-h * 60 + zone_ * -1 + 1.
if _time eq 1440. " minutes per day
" hmm, what should we do with it?
" as far as i know, sap's Abap VM does not support
" leap seconds
time_+4(2) = vars_-s.
else.
clear vars_. " wrong second
endif.
else.
clear vars_. " seconds out of range
endif.
endif.
endif.
if vars_ is initial.
clear:
time_,
zone_,
zone_unknown_,
offset_.
endif.
endform.
* Method: m_iso2time>
* Convert some ISO 8601 Time strings to ABAP representation
define m_iso2time>.
perform m_iso2time using &1 &2 &3 &4 &5 &6 &7.
end-of-definition.
form m_iso2time using " Parameters:
value(iso_) type any " - ISO 8601 date/time string
granularity_ type t_granularity " - degree of resolution
date_ type d " - date
time_ type t " - time
zone_ type i " - timezone difference in minutes
zone_unknown_ type c " - timezone specified as unknown
rc_ type sy-subrc. " - return code
data:
_l type i,
_exclusive type c,
_offset type i,
_raw type t_raw,
_rawdate type t_raw,
_rawtime type t_raw,
_date_vars type t_vars,
_time_vars type t_vars.
clear:
granularity_,
date_,
time_,
zone_,
rc_.
" check input parameter
if not iso_ is initial.
" check length
_raw = iso_.
if _raw eq iso_.
" adjust it
shift _raw left deleting leading space.
_l = strlen( _raw ).
translate _raw+0(_l):
to upper case, " switch to Capitals
using ',.', " change decimal commas to points
using ' T'. " date/time delimiter might be a space
" try to find out what string contains
if _raw ca 'T'.
" it contains both time and date
split _raw at 'T' into _rawdate _rawtime.
else.
" it contains either a date or a time
_rawdate = _rawtime = _raw.
_exclusive = 'X'.
endif.
" check date format
m_iso2time_date_setvar>
_rawdate _date_vars date_.
" check date format
m_iso2time_time_setvar>
_rawtime _time_vars time_ zone_ zone_unknown_ _offset.
case _exclusive.
when ' '. " time and date specified
if _date_vars is initial or _time_vars is initial.
rc_ = 2. " syntax error
endif.
when 'X'. " either time or date specified
if _date_vars is initial and _time_vars is initial.
rc_ = 3. " syntax error
elseif not _date_vars is initial
and not _time_vars is initial.
rc_ = 4. " ambigous, could be date or time
endif.
endcase.
if rc_ is initial.
concatenate _date_vars-granularity _time_vars-granularity
into granularity_.
if not _date_vars is initial and not _time_vars is initial.
add _offset to date_.
endif.
else.
clear:
date_,
time_,
zone_.
endif.
endif.
else.
rc_ = 1. " no string given
endif.
endform.
*
* S E L E C T I O N S C R E E N
*
parameters:
iso_(40) type c.
*
* G L O B A L S
*
data:
rc_ type sy-subrc,
date_ type d,
time_ type t,
zone_ type i,
unkn_ type c,
res_ type t_granularity.
*
* P B O ( )
*
initialization.
concatenate
sy-datum+0(4) '-'
sy-datum+4(2) '-'
sy-datum+6(2) 'T'
sy-uzeit+0(2) ':'
sy-uzeit+2(2) ':'
sy-uzeit+4(2) '+'
'01' ':'
'00'
into iso_.
*
* P A I ( )
*
start-of-selection.
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
All product names are trademarks of their respective companies. SAPNET.RU websites are in no way affiliated with SAP AG. SAP, SAP R/3, R/3 software, mySAP, ABAP, BAPI, xApps, SAP NetWeaver and any other are registered trademarks of SAP AG. Every effort is made to ensure content integrity. Use information on this site at your own risk.