Published on System iNetwork (http://systeminetwork.com)
Date Math in CL
By tzura
Created Apr 29 2004 - 04:00

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]

Copyright © Penton Media

Source URL: http://systeminetwork.com/node/61339

Links:
[1] http://publib.boulder.ibm.com/iseries/v5r2/ic2924/info/apis/ile4a1TOC.htm