Blog Archive

RPGLE date manipulation - Date difference, Add or substract days, months or years

Found this really nice article by by Joel Cochran in ITJungle.
Click here for more RPGLE Date Articles


With real date fields, and some additional supplied BIFs, date math couldn't be any easier. There are BIFs for adding and subtracting days, months, or years: appropriately, these are %days, %months, and %years. Below are some examples of how to use these BIFs with your date variable:
 d myDate          s               d   inz(d'2004-05-01')

   // myDate = '2004-05-01'
    myDate = myDate + %days(3) ;
   // myDate = '2004-05-04'

    myDate = myDate + %months(1) ;
   // myDate = '2004-06-04'

    myDate = myDate - %years(2) ;
   // myDate = '2002-06-04'

    *inlr = *on ;


Calculating the difference between two dates is also very easy, using another BIF, %diff. This BIF allows you to compare two dates and to calculate the difference in days, months, or years.
d myDate1         s               d   inz(d'2004-05-01')
d myDate2         s               d   inz(d'2004-05-08')
d diff_days       s              2s 0
d diff_months     s              2s 0
d diff_years      s              4s 0

    diff_days = %diff( myDate2 : myDate1 : *days );
    // diff_days = 7

    diff_months = %diff( myDate2 : myDate1 : *months ); 
    // diff_months = 0

    diff_years = %diff( myDate2 : myDate1 : *years );
    // diff_years = 0

    *inlr = *on ;

You can get a negative return value if the first parameter is an earlier date than the second parameter. To avoid this, either make sure that the higher date is always first or use the %abs (absolute value) BIF on the return value:
diff_years = %diff( myDate2 : myDate1 : *years );
diff_years = %abs(diff_years);
dsply diffyears;

You may want to embed this result in a character string. Typically, %char will do this for you nicely:
     myString = 'There is a difference of ' +
                        %char( %diff( myDate2 : myDate1 : *days ) ) +
                        ' days!' ;
      // myString = 'There is a difference of 7 days!'

By default this will suppress leading zeros. However, if you need leading zeros you may want to use %editc instead of %char, but you will quickly discover something interesting:
     myString = 'There is a difference of ' +
                        %editc( %diff( myDate2 : myDate1 : *days ) : 'X' ) +
                        ' days!' ;
      // myString = 'There is a difference of 0000000007 days!'

The return field for %diff is really 10 numeric! This means that if you want to use leading zeros, and still expect the correct number of characters, you will need to first move the value into an appropriately sized numeric field and then perform %editc. At first this seems strange, perhaps even silly, but once you realize that this BIF, and most others in this article, also apply to %time and %timestamp values, it is easy to conceive of needing 10 digits returned.


The %subdt BIF allows you to extract a portion of a date field, such as the day, month, or year.
d myDate          s               d   inz(d'2004-05-01')
d days            s              2s 0
d months          s              2s 0
d years           s              4s 0
d myString        s            128a

    days = %subdt( myDate : *days );
    // days = 1

    months = %subdt( myDate : *months );
    // months = 5

    years = %subdt( myDate : *years );
    // years = 2004 

    *inlr = *on ;

You can also use short cuts for the second parameter: *d instead of *days, *m instead *months, and *y instead of *years.

As I discussed with %diff above, using these results in character strings is no problem with %char, but if you use %editc you should be aware that %subdt is going to return a 10-digit numeric.
Read complete article here ...