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)