RPG
Developer Network News |
|
Wednesday, March 1, 2000 |
Editor: Robert Cozzi, Jr. |
Finding
the Last Day of the Month
Replacing those end-of-month
calculations with one procedure call
In order to provide a simpler interface for calculating the end of a month, we used Visual RPG Express's Procedure Wizard to generate the starter code for the ENDOFMONTH procedure. Then we added a few lines of RPG IV date operation codes and we were finished.
To use this procedure, simply include the prototype (lines 1 and 2) in any source member where ENDOFMONTH is called. Typically you would store the prototype in its own source member or in one that is little more than a bunch of related prototypes. For example, if you already downloaded our GetDayOfWeek procedure, you may want to include this new source in the same source members as those other date routines.
The syntax to call the end of month procedure is as follows:
C EVAL EndMonth = EndOfMonth( anyDate )
Where ENDMONTH is a date data-type variable, and anyDate is either a date data-type variable or a literal date value, such as D'2000-02-14' (which would yield D'2000-02-29' as the end of month).
The algorithm used is fairly simple. To calculate the end of the month you simply add one month to the dated in question. (See line 14 of the source listing.) This gives you the next month. If the date is 21 March 2000, by adding one month you end up with 21 April 2000. For the months that don't end in 31 days, if the date is 31 January 2000, by adding one month you end up with a date of 29 February 2000.
The next step is to calculate the ending date of the prior month (since that's what we wanted anyway). So we simply subtract the day of the month of the new date. That is if after adding one month to our date we ended up with 29 February 2000, we need to subtract 29 from that date to get 31 January 2000. It always works! (See line 16 of the source listing.)
To extract the day of the month we use the EXTRCT (extract) RPG IV operation code, specifying in Factor 2 the date and the type of duration we are extracting. (See line 15 of the source listing.)
Since the next month's day may not be the same as the current month's day we have to wait until we calculate a-month-from-now. The we use that new date's day to subtract (line 16).
Finally we return the new date value as Factor 2 of the RETURN operation. That value is returned to the calling expression.
To copy the ENDOFMONTH source to your PC and AS/400, highlight and copy the source code below. Then open your editor, such as Visual RPG Express, and paste from the clipboard to the editor. Save the file and upload it to your AS/400.
** Prototype for the Get ENDOFMONTH Procedure
.... D*ame+++++++++++EUDS.......Length+TDc.Functions+++++++++++++++++++++++
0001 D EndOfMonth PR D DatFmt(*ISO)
0002 D in_Date D Const DatFmt(*ISO)
** Implementation of the Get ENDOFMONTH Procedure
0003 P EndOfMonth B Export
0004 D EndOfMonth PI D DatFmt(*ISO)
0005 D in_Date D Const DatFmt(*ISO)
** Local variable begin here
0006 D NextMth S D DatFmt(*ISO)
0007 D nDay S 5I 0
0008 D EndOfMth S D
/* *************************************************** */
/* ** Visual RPG Express ProcWizard generated procedure */
C* ** Created: 29 Feb 2000
C*
** The TEST(E) Opcode requires V3R7 or later, otherwise use:
** The TEST Opcode with resulting indicator 2, as show in the
** comments below:
.....C**n01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq
0009 C** TEST in_Date 73
0010 C** if *IN73
0009 C TEST(E) in_Date
0010 C if %Error
0012 C return -1
0013 C endif
** To calculate the end of the month, use the following:
** Next Month = (Date + 1 month)
** End-Of-Month = Next Month - Day of next month
**
.... C**n01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq
0014 C in_Date AddDur 1:*Month NextMth
0015 C Extrct NextMth*Days nDay
0016 C NextMth SubDur nDay:*Days EndOfMth
0017 C return EndOfMth
0018 P EndOfMonth E