Search code examples
datetimetype-conversioncobolcics

How to convert 'YYYY-MM-DD hh:mm:ss.mmmmmm' (timezone CET (Amsterdam) and with DST) to 'CICS ABSTIME'?


I have a requirement to fill a PIC S9(15) COMP-3 variable with an CICS ABSTIME. (I believe this is the number of milliseconds that passed since the beginning op the year 1900)

My input is in the format YYYY-MM-DD hh:mm:ss.mmmmmm. This represents an timestamp in the CET timezone (Amsterdam) and follows the daylight saving time ('DST').

I've found part of the solution:

EXEC CICS CONVERTTIME
     DATESTRING ('Tuesday, 09-Oct-07 04:57:43 GMT')
     ABSTIME (WS-TIMESTAMP)
END-EXEC

Results in the ABSTIME +003400898263000

But CONVERTTIME can only handle 4 date format types (RFC 1123, RFC 3339, RFC 850, ASCtime) none of which that can handle both the timezone and automatically the DST See: https://www.ibm.com/support/knowledgecenter/SSGMCP_5.4.0/reference/commands-api/dfhp4_converttime.html

Which is the proper Cobol (/CICS) way of converting a date, including timezone and DST to ABSTIME?


Solution

  • I agree with Hogstrom that summer/winter (daylight/standard) time shifts have changed and are subject to future change, so fundamentally this is a data-driven problem to solve and re-solve. If you care about leap seconds, that's a similar problem. If you care about fairly recent historical time, the Netherlands had these interesting timezone offsets (standard time here):

    May 1, 1909, to July 1, 1937: UTC+0h19m32.13s (yes, seriously)

    July 1, 1937, to May 16, 1940: UTC+0h20m

    The Netherlands observed DST from 1916 to 1945, stopped observing it from 1946 to 1976, then started observing it again from 1977. And it's possible the Netherlands didn't start/end DST consistently according to the same date rules in the years when DST applied. (I'm not sure about that part.) There's active debate in the European Union right now about harmonizing time zones and possibly getting rid of summer/winter time shifts, so it's reasonable to plan ahead, to try to avoid embedding Y2K-like problems into this solution. Whatever you do, you want to try to make your code reasonably future proof.

    OK, with that background, and if the supplier of this time-related data insists on providing local Amsterdam time rather than helping you out with UTC, I think you ought to have some sort of input file, parameter list, or table that defines how to convert from Amsterdam local time to UTC. You may wish to throw an error if/when presented with dates/times earlier than January 1, 1977. If your application supports tracing or logging of some kind, I'd write out information about when the local to UTC time conversion ruleset was last updated. I'd also put some sort of date code comment/versioning information in the file/table/rule set. Programmatically apply the rules defined in that input file first, then pass the UTC into the code you have above. If you want to get a bit fancy (in a good way) you could define the time zone/DST rules in a BRMS such as IBM Operational Decision Manager (ODM) for z/OS if you have that (which may already have such rules), then call the BRMS from COBOL.

    Another possibility is to make the conversion from local time zone/DST to UTC using java.time. This article explains how that's done:

    https://www.baeldung.com/java-daylight-savings

    Naturally you can run Java programs in CICS (very well indeed), and Java Standard Edition is part of the base z/OS operating system, included and supported at no additional charge. (Liberty Profile is also part of CICS Transaction Server, although this is so simple you don't need Liberty.)

    The peril here is that if the Java distributor (IBM in this case) or, more likely, the system operator doesn't keep the Java runtime current, and then your program could apply an obsolete conversion rule from local to UTC whenever somebody decides to change the rules in the future. So I reluctantly prefer an input rule file/table/parameter list-based approach of some kind.

    OK, what input file/table/parameter list? Well, IANA's Timezone Database would be a really good choice:

    https://data.iana.org/time-zones/tz-link.html

    Your code would only likely need to handle a small subset of this database, but as the "source of truth" it's quite a good one.