Have it the way you want it by using the Convert Date and Time Format API.
Last month, in What's the Status of My Data Queue?, we used the Convert Date and Time Format (QWCCVTDT) API to format a date and time value stored in an internal format to a YYYYMMDDHHMMSS format much friendlier to work with, but we really didn't discuss how the API is used. This month, we'll look at some of the uses of QWCCVTDT.
The Convert Date and Time Format API converts date and time values from one format to another. For example, using the API you can:
- Access the current local time to character formats such as YYYYMMDDHHMMSS, MMDDYYYYHHMMSS, YYYYDDD HHMMSS, etc.
- Convert a system date time stamp value to character formats such as YYYYMMDDHHMMSS, MMDDYYYYHHMMSS, YYYYDDD HHMMSS, etc. (with a conversion to YYYYMMDDHHMMSS being what was done last month)
- Convert a date and time from one character format to another
- Convert a date and time from one time zone to another time zone
- Specify the level of time precision (milliseconds or microseconds) desired for input and output of the conversion process
Note that I would not necessarily use the QWCCVTDT API to actually perform all the format conversions listed above. The following program, for instance, shows how to access the local time, have it converted to YYYYMMDDHHMMSS character format, and then dsply the date and time value retuned by the API.
h dftactgrp(*no)
d CvtDat pr
d CvtDat pi
************************************************************
d CvtDatTim pr extpgm('QWCCVTDT')
d InpFmt 10a const
d InpValue 20a const options(*varsize)
d OutFmt 10a const
d OutValue 20a options(*varsize)
d ErrCde likeds(QUSEC)
d InpTZ 10a const options(*nopass)
d OutTZ 10a const options(*nopass)
d TZInfo 1a const options(*nopass)
d LenTZInfo 10i 0 const options(*nopass)
d PrecInd 1a const options(*nopass)
d InpTimInd 1a const options(*nopass)
************************************************************
d YYMDValue s 20a
************************************************************
/copy qsysinc/qrpglesrc,qusec
************************************************************
/free
CvtDatTim('*CURRENT' :' ' :'*YYMD' :YYMDValue :QUSEC);
dsply %subst(YYMDValue :1 :14);
*inlr = *on;
return;
// ********************************************************
begsr *inzsr;
QUSBPrv = 0;
endsr;
/end-free
This same result, however, could also be obtained quite easily using RPG-provided interfaces, with one possible solution shown in the following program.
h dftactgrp(*no)
d CvtDat pr
d CvtDat pi
****************************************************************
d YYMDValue s 20a
****************************************************************
/free
YYMDValue = %char(%timestamp() :*ISO0);
dsply %subst(YYMDValue :1 :14);
*inlr = *on;
return;
/end-free
In some cases, though, the API is the way to go.
As seen in the previous prototype, the QWCCVTDT API defines five required parameters and six optional parameters that are divided across two optional parameter groups. This month, we'll look at the required parameters. Next month, we'll review how the API can really assist you when needing to work with time values across users who are in different time zones.
The first required parameter is the input format. This is a Char(10) input value that defines the data you want converted. The actual data to be converted is passed in the second parameter. The special values supported are:
- *CURRENT to use the current system time (in which case the second parameter is not used)
- *DTS to use a system date time stamp
- *JOB to use the format found in the DATFMT job attribute
- *SYSVAL to use the format found in the QDATFMT system value
- A variety of common formats, such as *YYMD, *YMD, *MDYY, *MDY, *LONGJUL, and *JUL, where a single Y indicates a 2-digit year and YY indicates a 4-digit year
The second parameter is a variable-length input value that provides the date and time you want converted. As mentioned before, this parameter is not used (but must be passed) when the input format parameter is set to *CURRENT. One item to keep in mind is that the size of this parameter is implicitly assumed, based on the input format value. These are the assumed lengths based on the input format:
- *DTS will use the first 8 bytes of the input value.
- *YYMD, *MDYY, *DMYY, and *LONGJUL, when working with a millisecond precision (which is the default), will use the first 17 bytes of the input value.
- Other formats, when working with a millisecond precision, will use the first 16 bytes of the input value.
- *YYMD, *MDYY, *DMYY, and *LONGJUL, when working with a microsecond precision (parameter Precision indicator is set to '1'), will use the first 20 bytes of the input value.
- Other formats, when working with a microsecond precision, will use the first 19 bytes of the input value.
The third parameter is the desired output format. The special values supported are essentially those that can be used for the input format parameter, with the exception that you cannot specify *CURRENT.
The fourth parameter is a variable-length receiver variable for the API to use in returning the converted data and time value. The necessary size of this receiver variable is, like in the case of the input value, implicitly assumed, based on the output format value.
One item to be very careful about is the allocated size of this parameter within your application program. You'll note that there is no separate parameter for you to indicate the length of the receiver variable, so if you have the output format specified as *YYMD, the API is going to return 17 bytes of data. If your variable is less than 17 bytes in size, then storage is going to be overwritten (which can be a real pain to debug). That is partly why, in the previous sample program, I allocated the variable YYMDValue with a worst-case 20 bytes (the maximum amount of data returned by any format), though strictly speaking it only needs 17 bytes. There's no problem allocating more than is necessary, and I want to avoid having to remember in the future that, if I want to start using microsecond precision, I need to increase my variable allocations by 3 bytes (something easily forgotten).
The fifth parameter is the standard API error code structure.
Returning to our program of last month, GetDQInfo had obtained a system date time stamp and then called QWCCVTDT as in:
CvtDatTim('*DTS' :DQMsg.QMHMDT00
:'*YYMD' :YYMDValue :ErrCde);
This call is indicating that variable DQMsg.QMHMDT00 is a system date time stamp (input format is *DTS) and that the date and time value is to be converted to a YYYYMMDDHHMMSS format for further processing by the application program.
So just what is this *DTS format? It's basically an internal format for recording time in a consistent manner. The use of system date time stamps can be found in many areas of the system. You'll find *DTS as being a valid message data field format (FMT) on the Add Message Description (ADDMSGD) CL command (meaning you may need to work with *DTS values when sending or receiving a message), APIs such as Retrieve User Information (QSYRUSRI) (date password expires, password change date, etc.), and, as we saw last month, Retrieve Data Queue Message (QMHRDQM) (message enqueue date and time). For those readers who work with Machine Interface (MI) instructions, you also find system date time stamps, though referred to as a Time-of-Day (*TOD) clock value within MI documentation, on instructions such as Materialize Machine Attributes (MATMATR) and Materialize Time of Day Clock Attributes (MATTODAT). If you're interested in how system date time stamps are implemented within the system, you'll find the details under the MI topic Standard Time Format. When you're working with system date time stamps, I suspect you'll find the QWCCVTDT API to be, in general, the easiest way to go.
Next month, we'll look at some additional capabilities of the QWCCVTDT API.
Have Some System API Questions?
As usual, if you have any API questions, send them to me at
LATEST COMMENTS
MC Press Online