Although the subject matter of this post may seem simple to the more experienced RPG black belts, I am creating this post in response to questions I have receieved recently from two collegues. I was asked if there was an "easy" way to determine the date of the end of the month entered. They both had examples in RPG III and were sure that there must be simpler way.
In RPG III I could determine the date of the last day of the month like this:
E DAYS 12 12 2 0 * IINPUT DS I 1 20MM I 3 40DD I 5 80YEAR * C MOVE *DATE INPUT C MM IFNE 2 C Z-ADDDAYS,MM DD C ELSE C YEAR DIV 400 X 40 C MVR X C X IFEQ *ZERO C MOVE '29' DD C ELSE C MOVE '28' DD C ENDIF C ENDIF ** 31XX31303130313130313031
In RPGLE/RPG IV it is far easier using a date field and built in functions, BIFs.
In this example I am going to take the current date, use it to calculate the date for the end of this month, and present the date in USA format. I could code it like this:
01 D wkDate S D 02 D Output S 10 03 /free 04 wkDate = %date() - %days((%subdt(%date():*days) - 1)) 05 + %months(1) 06 - %days(1) ; 07 Output = %char(wkDate:*usa/) ;
Line 4 is where the "action" starts.
The first BIF is %DATE, which gives me the current date, for today it is 2013-08-08 (I am giving the date in *ISO format to make it easier for everyone to understand as our international readers could use a different date format to the USA).
From that I subtract the (current number of days - 1) to get the first of the month. To do this I use the %SUBDT BIF to extract the number of days, *days, from today's date, %DATE(). This gives me the number 8. I subtract one from that to give me 7. Then using the %DAYS BIF I subtract that number from the today's date. Which gives me:
(today - (day_of_month - 1) days) = 2013-08-01.
I add one month to the date using the %MONTHS BIF, line 5. Therefore, the date is now 2013-09-01.
Finally I subtract one day from the date, line 6, using the %DAYS BIF. This gives me 2013-08-31.
I then convert, on line 7, the date to an *USA format (MMDDYYYY) alphanumeric field with date separator character of '/'. In our example the field Output would contain the value '08/31/2013'.
As you can see this is a lot smarter way of calculating the last day of the month versus the way we had to do it using RPG III.
You can learn more about these BIFs on the IBM website:
This article was written for IBM i 7.1, and it should work with earlier releases too.
Friday August 9, 2013: I was sent a number of interesting messages on how this could be done using SQL. Therefore, I created a new post, Calculating end of month part II, for the best example.