Consultor Eletrônico



Kbase 20665: 4GL/ABL: How to convert UNIX/JMS Timestamp values to Progress/ OpenEdge Date and Time Values?
Autor   Progress Software Corporation - Progress
Acesso   Público
Publicação   18/02/2009
Status: Unverified

GOAL:

4GL/ABL: How to convert UNIX/JMS Timestamp values to Progress/ OpenEdge Date and Time Values?

GOAL:

How to convert the SonicMQ getJMSTimestamp API function returned values to Progress Date and Time Values?

GOAL:

How to convert the decimal UNIX Timestamp values to human readable Progress Date and Time Values?

GOAL:

How to convert the decimal time value returned by the SonicMQ API function getJMSTimestamp function to human readable Progress Date and Time Values?

FACT(s) (Environment):

All Supported Operating Systems
Progress 9.x
OpenEdge 10.x
OpenEdge Category: Language (4GL/ABL)

FIX:

When Progress works with UNIX, JAVA, etc, it might receive a date and time represented by a decimal value that can be returned from an outside function or method such as getJMSTimestamp. The UNIX timestamp symbolizes the instant of time that is the time in seconds after the standard base time known as "the epoch" (midnight GMT on January 1, 1970). The JMS timestamp is the same as a UNIX timestamp except that it is measured with milliseconds included in it.
The following procedure demonstrates how to convert values returned in UNIX Timestamp format and the SonicMQ getJMSTimestamp API function to a human readable Progress date and time. A commented version of this procedure is listed below to explain the logic involved:
DEFINE VARIABLE dDateVariable AS DATE NO-UNDO.
DEFINE VARIABLE iTimeVariable AS INTEGER NO-UNDO.
DEFINE VARIABLE iMilliSeconds AS INTEGER NO-UNDO.
RUN convertUnixTimestamp(INPUT 982608406.0, OUTPUT dDateVariable, OUTPUT iTimeVariable).
MESSAGE
dDateVariable STRING(iTimeVariable, "HH:MM:SS") "UTC":U
VIEW-AS ALERT-BOX INFO.
RUN convertJMSTimestamp(INPUT 982608406999.0, OUTPUT dDateVariable, OUTPUT iTimeVariable, OUTPUT iMilliSeconds).
MESSAGE
dDateVariable STRING(iTimeVariable, "HH:MM:SS") iMilliSeconds "UTC":U
VIEW-AS ALERT-BOX INFO.
QUIT.
PROCEDURE convertUnixTimestamp:
DEFINE INPUT PARAMETER ipdTimeStamp AS DECIMAL NO-UNDO.
DEFINE OUTPUT PARAMETER opdtDateParam AS DATE NO-UNDO.
DEFINE OUTPUT PARAMETER ipiTimeParam AS INTEGER NO-UNDO.
/* Seconds per day */
DEFINE VARIABLE iSecondsPerDay AS INTEGER NO-UNDO.
/* Seconds per year */
DEFINE VARIABLE iSecondsPerYear AS INTEGER NO-UNDO.
/* Variables to hold our calculation so far */
DEFINE VARIABLE iYearVariable AS INTEGER NO-UNDO.
DEFINE VARIABLE iDayVariable AS INTEGER NO-UNDO.
DEFINE VARIABLE iSecondsLeft AS INTEGER NO-UNDO.
DEFINE VARIABLE iLeapDays AS INTEGER NO-UNDO.

ASSIGN
iSecondsPerDay = 60 * 60 * 24
iSecondsPerYear = iSecondsPerDay * 365
/* Since it is impossible to have 365 or more leap years since 1970 the following
calculation will always work and always come up with the correct year. */
iYearVariable = INTEGER(TRUNCATE (ipdTimeStamp / iSecondsPerYear, 0))
/* Calculate the number of seconds that have elapsed in the current year so far. */
iSecondsLeft = INTEGER(ipdTimeStamp - (iYearVariable * iSecondsPerYear)).
/*
Now we have to adjust the seconds left in the current year for the number of Feb 29th days
that have elapsed since 1970, excluding the current year, which will be handled further below.
*/BR> /* How many leapyears since 1970? 1972 is the first one. */
IF iYearVariable > 2 THEN DO:
ASSIGN /* subtract 3 from year to get relative to 1973 */
/* 1973 = 1, 1977 = 2, etc. We don't include the current year in this */
iLeapDays = INTEGER(TRUNCATE((iYearVariable - 3) / 4, 0)) + 1
iSecondsLeft = iSecondsLeft - (iLeapDays * iSecondsPerDay).
END.
/* Now the year and seconds since the beginning of the year are accurate */
ASSIGN
/* Now the year and day are in julian format (almost). Julian would have year 2000 as "00", but we have "30". */
/* If the current year is a leap year this is handled here. DATE math allows us to add days to a date - add to Jan 1. */
iDayVariable = INTEGER(TRUNCATE(iSecondsLeft / iSecondsPerDay, 0))
opdtDateParam = DATE('01/01/':U + STRING(iYearVariable + 1970)) + iDayVariable
/* The number of seconds since midnight of the date above */
ipiTimeParam = iSecondsLeft - (iDayVariable * iSecondsPerDay).

END PROCEDURE. /* convertUnixTimestamp */

PROCEDURE convertJMSTimestamp:
DEFINE INPUT PARAMETER ipdTimeStamp AS DECIMAL NO-UNDO.
DEFINE OUTPUT PARAMETER opdtDateParam AS DATE NO-UNDO.
DEFINE OUTPUT PARAMETER ipiTimeParam AS INTEGER NO-UNDO.
DEFINE OUTPUT PARAMETER piMilliSeconds AS INTEGER NO-UNDO.

DEFINE VARIABLE dTimestamp AS DECIMAL NO-UNDO.
/* A JMS Timestamp is the same as a UNIX timestamp except it also has milliseconds in it. */
ASSIGN
dTimestamp = TRUNCATE(ipdTimeStamp / 1000.0, 0)
/* Can't use MODULO since it operates on INTEGER, and our numbers are bigger than an INTEGER allows (possibly) */
piMilliSeconds = INTEGER(ipdTimeStamp - (dTimestamp * 1000.0)).

RUN convertUnixTimestamp(INPUT dTimestamp, OUTPUT opdtDateParam, OUTPUT ipiTimeParam).
END PROCEDURE. /* convertJMSTimestamp */.