RPG Developer Network News
www.RPGIV.com

It's not your father's Q38
(c) 1999 by Robert Cozzi Jr. All rights reserved.

Monday, January 18, 1999

Editor: Robert Cozzi, Jr.

Adding RPG IV Date Support to RPGIII
Everybody has RPG IV
One of the benefits of including RPG IV with the RPG compiler on the AS/400 is that even if your company doesn't move RPG IV quick enough, you can still take advantage of some of the new features in RPG IV. By interfacing some of your existing programs with small RPG IV programs, you can pass parameters to these programs and have them do the cool RPG IV stuff. They can of course also return values to your lowly old RPGIII program.

The biggest example of this, I believe, is the native date and time support in RPG IV. At no time in history has this kind of support been as important as it is today. All new applications and all existing applications that process date values need to be accurate and limitless.

RPG IV supports three integrated date operation codes, they are:

  1. ADDDUR – Add Duration
  2. SUBDUR – Subtract Duration
  3. TEST(D) – Test for valid Date

The ADDDUR operation adds a period of time, known as a duration, to a date or time value. You specify the kind of duration to add to your date field. ADDDUR supports adding days, months, or years for date fields, or hours, minutes, seconds, or microseconds to time values. See the list of duration codes later in this article.

The SUBDUR operation performs two operations. (1) It subtracts a duration from a date or time value. Like the ADDDUR operation, you specify the duration code. (2) It subtracts one date or time value from another, calculating the period of time between the two date or time values. This period of time is also known as a duration. In this case, the duration code identifies the result value. That is you specify whether you want SUBDUR to calculate the number of days, months, years, hours, minutes or seconds between the two values.

The TEST(D) operation checks a field for a valid date, time or timestamp value. The Result field contains the date value being validated. Resulting indicator 2 is set on by the TEST(D) operation if the validation fails.

The benefit of using these operation codes is that they always produce the correct result. For example, to calculate the number of days between two dates, one SUBDUR operation is performed. There is no need to call "release 5 of that hand-coded last date routine you'll ever need". SUBDUR does it all easily.

 

Intefacing RPG IV with RPG III
As you know, RPGIII does not support date fields, and IBM plans no enhancements to RPGIII. While this is an unfortunate situation, we can still take advantage of RPG IV date operations in RPGIII by writing a stub.

A stub is a relatively new concept to RPG programmers. It is a piece of code that interfaces with an API (application program interface) or function. A stub provides a customized interface, making it possible to evoke a function not normally available. Effectively, by writing an RPG IV program that performs the date operation code, and providing a parameterized interface to those date routines, we provide a stub to the RPG IV ADDDUR and SUBDUR operation codes. The results are returned to the program's caller.

There are three stubs included with this article that provide access to the ADDDUR and SUBDUR operations. There is one for the ADDDUR operation and two for the SUBDUR operation. The reason there are two for SUBDUR is because it performs two functions—subtracting a duration to calculate a new date, and calculating a duration by subtracting two date values.

The three stubs are written, of course, in RPG IV. They are  CZADDDUR, CZSUBDAT, and CZSUBDUR and can be called from any high-level language program, specifically RPGIII. They provide the ability to add or subtract a duration from a date value. The input is a 7-digit packed field that contains a 6 or 7-position date value. The returned value is an accurately calculated new date value or a properly calculated duration value.

None of the stubs in this article accept 8-digit year values, although they are all Y2K-safe. The thinking is that if you need this function, it is to provide Y2K support to 6-digit year values. If you've already gone to 8-position date values, you're probably calling enhanced routines and therefore won't need these stubs. Following the logic of the programs, you could easily add 8-digit year support to these routines, or create new stubs that handle 8-digit dates. For example a CZADDDUR8 program would accept a 9-digit packed value and perform 8-position date arithmetic.

 

CZADDDUR (Add Duration)
The czADDDUR program accepts a starting date, a date format, a duration and duration code. It adds the duration to the date and returns a new date. This like all three stubs, is Y2K-safe. Since the three stubs word only with dates, only months, days, years, and weeks can be added to the start date. See the parameter list for the CZADDDUR for a description of each of its parameters.

Click here to download the source for czadddur.rpgle

 

CZSUBDAT (Subtract Dates)
The czSUBDAT program accepts starting and ending date values, subtracts them, and returns a duration. The duration being returned is controlled by the duration code that is also passed to the program. The duration code can be months, days, years, or weeks between the two date values. See the parameter list for the CZSUBDAT for a description of each of its parameters.

Click here to download the source for czsubdat.rpgle

 

CZSUBDUR (Subtract Duration)
The czSUBDUR program accepts starting a starting date, a duration value and duration code. The duration subtracted from the starting date. The resulting date value is returned to the caller in the format specified by the returned date format code. See the parameter list for the CZSUBDUR for a description of each of its parameters.

Click here to download the source for czsubdur.rpgle

 

Other Stubs to Consider
There are several other date-related stubs that could be easily created. The TEST operation code is one potential candidate. The ability to validate a field's value for a valid date value is very important. The TEST operation code's ability to test numeric, character or date fields is wonderful. Another would be one that

I've already posted another "stub" that retrieves the day of the week. The source code for that routine, czGETDAY is available by clicking here.

 

czADDDUR Parameter Interface
Parameter Attributes Description
RTNCODE (OUTPUT) Pkd(7,0) Return code.
STARTDATE (input) Pkd(7,0) Start date. Must be in the format specified in the STARTFMT parameter.
STARTFMT (input) Char(10) Starting date format code.

Any 6 or 7-digit date format can be specified, including the following: *MDY, *YMD, *DMY, *JUL, *CYMD

ENDDATE (OUTPUT) Pkd(7,0) The end date. Calculated by adding the duration value to the start date. It will be in the format specified in the ENDFMT parameter.
ENDFMT (input) Char(10) Ending date format code.

Any 6 or 7-digit date format can be specified, including the following: *MDY, *YMD, *DMY, *JUL, *CYMD

DUR (input) Pkd(7,0) Duration.

The duration value is added to the start date. It is interpreted based on the value specified in the DURFMT parameter.

DURFMT (input) Char(10) Duration code.

The supported duration codes including the following:

*D, *DAY, *DAYS
*M, *MONTH, *MONTHS
*Y, *YEAR, *YEARS
*W, *WEEK, *WEEKS

NOTE: There is no difference in the 3 styles of each duration code.

 

czSUBDAT Parameter Interface
Parameter Attributes Description
RTNCODE (OUTPUT) Pkd(7,0) Return code.
STARTDATE (input) Pkd(7,0) Start date. Must be in the format specified in the STARTFMT parameter.
STARTFMT (input) Char(10) Starting date format code.

Any 6 or 7-digit date format can be specified, including the following: *MDY, *YMD, *DMY, *JUL, *CYMD

ENDDATE (input) Pkd(7,0) The ending date. Subtracted from the start date to produce the duration. It must be in the format specified in the ENDFMT parameter.
ENDFMT (input) Char(10) Ending date format code.

Any 6 or 7-digit date format can be specified, including the following: *MDY, *YMD, *DMY, *JUL, *CYMD

DUR (OUTPUT) Pkd(7,0) Duration.

The duration value that is calculated by subtracting the end date from the start date. It is in the format indicated by the DURFMT parameter.

DURFMT (input) Char(10) Duration code.

The supported duration codes including the following:

*D, *DAY, *DAYS
*M, *MONTH, *MONTHS
*Y, *YEAR, *YEARS
*W, *WEEK, *WEEKS

NOTE: There is no difference in the 3 styles of each duration code.

 

czSUBDUR Parameter Interface
Parameter Attributes Description
RTNCODE (OUTPUT) Pkd(7,0) Return code.
STARTDATE (input) Pkd(7,0) Start date. Must be in the format specified in the STARTFMT parameter.
STARTFMT (input) Char(10) Starting date format code.

Any 6 or 7-digit date format can be specified, including the following: *MDY, *YMD, *DMY, *JUL, *CYMD

ENDDATE (OUTPUT) Pkd(7,0) The end date. Calculated by subtracting the duration value from the start date. It will be in the format specified in the ENDFMT parameter.
ENDFMT (input) Char(10) Ending date format code.

Any 6 or 7-digit date format can be specified, including the following: *MDY, *YMD, *DMY, *JUL, *CYMD

DUR (input) Pkd(7,0) Duration.

The duration value is subtracted from the start date. It is interpreted based on the value specified in the DURFMT parameter.

DURFMT (input) Char(10) Duration code.

The supported duration codes including the following:

*D, *DAY, *DAYS
*M, *MONTH, *MONTHS
*Y, *YEAR, *YEARS
*W, *WEEK, *WEEKS

NOTE: There is no difference in the 3 styles of each duration code.

 

RPG IV Duration Codes
*YEARS for the year. Short hand is: *Y

*MONTHS for the month. Short hand is: *M

*DAYS for the day of the month. Short hand is: *D

*HOURS for the hours. Short hand is: *H

*MINUTES for the minutes. Short hand is: *MN

*SECONDS for the seconds. Short hand is: *S

*MSECONDS for the microseconds. Short hand is: *MS