Q: Is it possible to do date math in a CL program? Or do I have to call an ILE RPG program?
A: It's a little easier to do date math in ILE RPG because of the date op- codes, but it's still possible to do it in CL. The best way to do date math in CL is by converting the dates to "lilian." Lilian dates are a count of days starting with October 14, 1582.
Since a lilian date is a count of days, you can add or subtract days from them using ordinary addition and subtraction.
IBM provides several APIs to work with lilian dates. Here is a sample program that demonstrates a few of them:
/* CL Date Math demo. Scott Klement, April 29, 2004 +
+
To compile this, type: +
CRTBNDCL PGM(DATEDEMO) SRCFILE(xxx/xxx) DFTACTGRP(*NO) */
PGM
DCL VAR(&LILIAN) TYPE(*CHAR) LEN(4)
DCL VAR(&JUNK1) TYPE(*CHAR) LEN(8)
DCL VAR(&JUNK2) TYPE(*CHAR) LEN(23)
DCL VAR(&NICE) TYPE(*CHAR) LEN(10)
DCL VAR(&WEEKS) TYPE(*DEC) LEN(10 0)
DCL VAR(&TEMP) TYPE(*DEC) LEN(10 0)
DCL VAR(&DOW) TYPE(*DEC) LEN(1 0)
DCL VAR(&FROM) TYPE(*CHAR) LEN(4)
DCL VAR(&TO) TYPE(*CHAR) LEN(4)
DCL VAR(&FROMDT) TYPE(*CHAR) LEN(10)
DCL VAR(&TODT) TYPE(*CHAR) LEN(10)
DCL VAR(&DAYS) TYPE(*DEC) LEN(5 0)
DCL VAR(&MYDATE) TYPE(*CHAR) LEN(6)
DCL VAR(&CHARDY) TYPE(*CHAR) LEN(5)
DCL VAR(&BDATE) TYPE(*CHAR) LEN(31)
/* Get local time from system: When this call is +
complete, &LILIAN will contain the number of +
days between today and Oct 14, 1582. */
CALLPRC PRC(CEELOCT) PARM(&LILIAN &JUNK1 &JUNK2 *OMIT)
/* Adding 1 to &LILIAN will produce tomorrow's date */
CHGVAR VAR(%BIN(&LILIAN)) VALUE(%BIN(&LILIAN) + 1)
/* The CEEDATE API can be used to format a lilian date +
as something that a person can read: */
CALLPRC PRC(CEEDATE) PARM(&LILIAN 'YYYY-MM-DD' &NICE *OMIT)
SNDUSRMSG MSG('Tomorrow will be' *BCAT &NICE) +
MSGTYPE(*INFO)
/* CEEDATE can also be used to determine what day of the week +
tomorrow is: */
CALLPRC PRC(CEEDATE) PARM(&LILIAN 'Wwwwwwwwww' &NICE *OMIT)
SNDUSRMSG MSG('Tomorrow is' *BCAT &NICE) +
MSGTYPE(*INFO)
/* Sometimes you don't want to start with today's date.+
In that case, you can get a lilian date using the +
CEEDAYS API. For this example, the date is in +
MMDDYY format: */
CHGVAR VAR(&MYDATE) VALUE('082072')
CALLPRC PRC(CEEDAYS) PARM(&MYDATE 'MMDDYY' &FROM *OMIT)
CALLPRC PRC(CEELOCT) PARM(&TO &JUNK1 &JUNK2 *OMIT)
CHGVAR VAR(&DAYS) VALUE(%BIN(&TO) - %BIN(&FROM))
CHGVAR VAR(&CHARDY) VALUE(&DAYS)
CALLPRC PRC(CEEDATE) PARM(&FROM +
'Wwwwwwwwwz, Mmmmmmmmmz DD, YYYY' +
&BDATE *OMIT)
SNDUSRMSG MSG('Tim was born on' *BCAT &BDATE *TCAT '. +
He is' *BCAT &CHARDY *BCAT 'days old.') +
MSGTYPE(*INFO)
/* Shipping will take 8-10 days. When will our user +
receive a package? */
CALLPRC PRC(CEELOCT) PARM(&LILIAN &JUNK1 &JUNK2 *OMIT)
CHGVAR VAR(%BIN(&FROM)) VALUE(%BIN(&LILIAN) + 8)
CALLPRC PRC(CEEDATE) PARM(&FROM 'YYYY-MM-DD' &FROMDT *OMIT)
CHGVAR VAR(%BIN(&TO)) VALUE(%BIN(&LILIAN) + 10)
CALLPRC PRC(CEEDATE) PARM(&TO 'YYYY-MM-DD' &TODT *OMIT)
SNDUSRMSG MSG('Shipment takes 8-10 days, it will +
arrive between' *BCAT &FROMDT *BCAT 'and' +
*BCAT &TODT) MSGTYPE(*INFO)
/* Another way to find out the day of the week is to divide the +
date by 7 and take the remainder. Since Lilian Date 1 +
(Oct 14, 1582) was a Friday, this will yield a number from +
0=Thursday to 6=Wednesday */
CALLPRC PRC(CEELOCT) PARM(&LILIAN &JUNK1 &JUNK2 *OMIT)
CHGVAR VAR(&WEEKS) VALUE(%BIN(&LILIAN) / 7)
CHGVAR VAR(&TEMP) VALUE(&WEEKS * 7)
CHGVAR VAR(&DOW) VALUE(%BIN(&LILIAN) - &TEMP)
/* Perhaps our business week ends every Friday and we need +
to know when the next Friday is. We can use &DOW to +
calculate what the date will be. */
IF (&DOW *LE 1) DO
CHGVAR VAR(&DOW) VALUE(1 - &DOW)
ENDDO
ELSE DO
CHGVAR VAR(&DOW) VALUE(8 - &DOW)
ENDDO
CHGVAR VAR(%BIN(&LILIAN)) VALUE(%BIN(&LILIAN) + &DOW)
CALLPRC PRC(CEEDATE) PARM(&LILIAN 'YYYY-MM-DD' &NICE *OMIT)
SNDUSRMSG MSG('The next week ending date is' +
*BCAT &NICE) MSGTYPE(*INFO)
ENDPGM
Detailed information on the CEE Date & Time APIs can be found at the following link: http://publib.boulder.ibm.com/iseries/v5r2/ic2924/info/apis/ile4a1TOC.htm [1]
Links:
[1] http://publib.boulder.ibm.com/iseries/v5r2/ic2924/info/apis/ile4a1TOC.htm