EGL Development User Group - Group home

How to get a full timestamp value for z/OS or zVSE COBOLGen environments

By Jiyong Huang posted Wed April 01, 2020 09:21 PM

  

As you may have noticed, when using COBOL, the EGL currentTimeStamp function call is unable to return more precision than the 100th of a second value. Take this timestamp for example:

myTimeStamp timestamp("yyyyMMddhhmmssffffff"); 

It has defined all 6 decimal positions, however in COBOL environments, the last 4 positions of ffffff will always be zero.

This is because the native COBOL statement to get the time value does not return more than 2 decimal positions. However, there is a way to get the entire value, as I will show you here.

 

Instead of using the EGL function for currentTimeStamp, you can instead call out to an assembler program (which I have attached here), that can provide the complete timestamp value.

To do this, you would define the EGL build descriptor's linkage table for the assembler program (in my example this is called USRTMSTP), to have parmForm of OSLINK. This is mandatory whether you are using batch, CICS, or IMS. It is up to you as to whether you define this as statically or dynamically called. Statically called will be far faster, and since this assembler code will likely never need to be changed, it might be a good choice.

 

Once the build descriptor has been defined with the linkage table entry, you can generate this example EGL code to see how it works:

package zosCics;

program timeStampExample type BasicProgram {alias = "TSEXMPL"}
    // all 20 positions must be specified, as that is return value from the USRTMSTP program
    myTimeStamp timestamp("yyyyMMddhhmmssffffff"); 
    function main()
        call "USRTMSTP"(myTimeStamp) {IsExternal = yes};
        writestdout("Time stamp=" + myTimeStamp);
    end
end

 

The above EGL code will call out to the assembler program, passing the full 20 character area of the timestamp. The assembler program will always write 20 bytes of data, so you must make sure that you provide a full 20 byte timestamp area.

Here is the assembler code for the USRTMSTP program. This is an example and you are free to use it, but it is provided AS IS and will not be maintained by IBM:

//ASM      EXEC PGM=ASMA90,PARM='LIBMAC,NODECK,ALIGN,OBJ'
//SYSLIB   DD  DISP=SHR,DSN=SYS1.MACLIB
//         DD  DISP=SHR,DSN=CEE.SCEEMAC
//SYSIN    DD  *
***********************************************************************
* CALL "USRTMSTP" USING 20 CHARACTER WORK AREA                        *
***********************************************************************
USRTMSTP CEEENTRY PPA=PARMPPA,AUTO=WORKSIZE,MAIN=NO
         USING WORKAREA,R13
R1       EQU   1
R4       EQU   4
R13      EQU   13
***********************************************************************
* SAVE THE ORIGINAL PARM LIST IN R4                                   *
***********************************************************************
         LR    R4,R1               SAVE THE PARM LIST
***********************************************************************
* THIS PROGRAM WILL GET THE DATE/TIME USING THE TIME MACRO            *
***********************************************************************
         TIME  STCK,TODCLOCK,ZONE=LT,LINKAGE=SVC
         STCKCONV STCKVAL=TODCLOCK,CONVVAL=MYTIME,TIMETYPE=DEC,        X
               DATETYPE=YYYYMMDD,MF=(E,MYSTCK)
         OI    MYTIME+12,X'0F'
         UNPK  MYDATE(9),MYTIME+8(5)
         TIME  MIC,TODCLOCK,ZONE=LT,LINKAGE=SVC
         STCKCONV STCKVAL=TODCLOCK,CONVVAL=MYTIME,TIMETYPE=DEC,        X
               DATETYPE=YYYYMMDD,MF=(E,MYSTCK)
         OI    MYTIME+6,X'0F'
         UNPK  MYDATE+8(13),MYTIME(7)
         L     R1,0(R4)
         MVC   0(20,R1),MYDATE
***********************************************************************
* RETURN TO THE CALLER                                                *
***********************************************************************
EXIT     CEETERM RC=0
PARMPPA  CEEPPA ,
**********************************************************************
* WORKING STORAGE AREA                                               *
**********************************************************************
WORKAREA DSECT
         ORG   *+CEEDSASZ
TODCLOCK DS    D
MYTIME   DS    CL16
MYDATE   DS    CL32
MYSTCK   STCKCONV MF=L
WORKSIZE EQU   *-WORKAREA
         CEEDSA ,
         CEECAA ,
         END   USRTMSTP
/*
//SYSPRINT DD  SYSOUT=*
//SYSUT1   DD  UNIT=SYSALLDA,SPACE=(CYL,(5,5))
//SYSUT2   DD  UNIT=SYSALLDA,SPACE=(CYL,(5,5))
//SYSUT3   DD  UNIT=SYSALLDA,SPACE=(CYL,(5,5))
//SYSLIN   DD  DISP=SHR,DSN=your.OBJECT.dataset(USRTMSTP)
//LKED1D   EXEC PGM=IEWL,REGION=3000K,
//             PARM='LIST,XREF,RENT'
//SYSLMOD  DD  DSN=your.LOAD.dataset(USRTMSTP),DISP=SHR
//SYSPRINT DD  SYSOUT=*
//SYSUT1   DD  UNIT=SYSALLDA,SPACE=(CYL,(3,3))
//SYSLIB   DD  DISP=SHR,DSN=CEE.SCEELKED
//SYSLIN   DD  DISP=SHR,DSN=your.OBJECT.dataset(USRTMSTP)

 

 

0 comments
1 view