Brief: In our final installment of this introductory ILE RPG series, we examine the support for date data types. ILE RPG can define date, time and timestamp fields corresponding with the DDS support for these data types. It also provides support for date arithmetic, conversion from one date type to another, and conversion to and from numeric and character fields.
Last month we saw the introduction of built-in functions, which can substantially reduce program development and maintenance time, in some cases reducing complex routines or called programs in RPG/400 to a single line of code in ILE RPG.
In this article, we look at one of the most exciting features of ILE RPG- support for date data types. Date data types have been available on the AS/400 since V2R2; but because they cannot be directly processed in RPG/400, their usefulness has been limited. ILE RPG provides full support for date data types and date arithmetic. This support makes it easy to calculate the difference between two dates or to increment a date by a number of days, taking into account the varying number of days in each month. For example, 1992 is a leap year. If you add 30 days to January 31, 1992, ILE RPG correctly calculates the result as March 1, 1992; if you add 30 days to January 31, 1993, the result is March 2, 1993.
The "Date, Time and Timestamp Data Types" sidebar (page 100) covers the possible formats for date fields in OS/400. Within ILE RPG, you can define fields or constants as date (D), time (T) or timestamp (Z) data types. For the rest of this article, we'll refer to such fields generically as date fields unless an example specifically applies to time or timestamp fields. The length of a date field is determined by the data type and the date format-it should not be coded as part of the definition.
The default format for date fields in an ILE RPG program can be specified in the Header specification (H-spec) using the DATFMT and TIMFMT keywords. (For more information on H-spec keywords, see "An Introduction to ILE: Part 1," MC, March 1994.) If these keywords are not used, the default format is International Standards Organization (*ISO) format.
Date Field Definitions
1 shows samples of defining date and time fields with initialized values. Since no H-spec exists in the program, date fields that do not include a DATFMT or TIMFMT keyword default to *ISO format; and the *ISO format must be used to initialize all date fields regardless of their format.
Figure 1 shows samples of defining date and time fields with initialized values. Since no H-spec exists in the program, date fields that do not include a DATFMT or TIMFMT keyword default to *ISO format; and the *ISO format must be used to initialize all date fields regardless of their format.
In the first example in 1, the D in position 40 defines the field eur_date as a date field. Since *EUR is specified for the DATFMT keyword, the date is internally represented in IBM European Standard format (i.e., dd.mm.yyyy) and is automatically defined as 10 characters in length. The INZ parameter initializes the field to 16.12.1994 (December 16, 1994). Even though the field eur_date is defined as a *EUR format date field, the value on the INZ parameter must be in *ISO format (i.e., 1994-12-16). Several other examples of date field definitions are included in 1.
In the first example in Figure 1, the D in position 40 defines the field eur_date as a date field. Since *EUR is specified for the DATFMT keyword, the date is internally represented in IBM European Standard format (i.e., dd.mm.yyyy) and is automatically defined as 10 characters in length. The INZ parameter initializes the field to 16.12.1994 (December 16, 1994). Even though the field eur_date is defined as a *EUR format date field, the value on the INZ parameter must be in *ISO format (i.e., 1994-12-16). Several other examples of date field definitions are included in Figure 1.
The T in position 40 defines the field hms_time as a time field. Since *HMS is specified for the TIMFMT keyword, the time is internally represented in Hours:Minutes:Seconds format (i.e., hh.mm.ss). The INZ parameter initializes the field to 30 seconds after 6:06 p.m. In a similar manner, the field usa_time is defined as a *USA format time field with an implied length of eight. While the internal format of this field is hh:mm AM or hh:mm PM, the value on the INZ parameter must be in *ISO format (i.e., hh.mm.ss).
Literals cannot be specified in a date format different from the default for the program. Therefore, the value for all date and time literals must be represented in the format specified in the H-spec or *ISO format if no format is specified. Date literals should be prefixed by D, T and Z for date, time and timestamp values. Using the *ISO format, D'1994-12-16' defines a date literal with a length of 10 and a value of December 16, 1994. T'18.06.30' defines a time literal with a length of eight and a value of 30 seconds after 6:06 p.m. Z'1994-12-16-18.06.30' defines a timestamp literal with a length of 26 and a value of 30 seconds after 6:06 p.m. on December 16, 1994. (If the microseconds portion of a timestamp literal is not specified, it defaults to '000000' and its length remains 26).
2 shows another sample of defining date and time fields with initialized values. In this sample, a DATFMT of *USA and TIMFMT of *HMS are specified on the H-spec.
Figure 2 shows another sample of defining date and time fields with initialized values. In this sample, a DATFMT of *USA and TIMFMT of *HMS are specified on the H-spec.
As in the prior sample, the field eur_date is defined as a 10-character, *EUR- format (dd.mm.yyyy) date field. But this time the initialization value must be provided in *USA format (mm/dd/yyyy) because of the DATFMT keyword specified in the H-spec.
When the LIKE keyword is used, the DATFMT and TIMFMT keywords are not allowed. The field eur_date2 is defined as a 10-character, *EUR-format (dd.mm.yyyy) date field that takes its format (but not its value) from the field eur_date.
The field usa_date is defined as an eight-character, *USA-format date field with a format of *USA&. The ampersand (&) changes the default separator character from a slash (/) to a blank. The value of the field usa_date will be 12 16 1994, while the value of the field usa_date2 will be 12/16/1994.
Default Values
We've already shown how date fields can be initialized to a specific value using the INZ keyword in the D-specs. You can also initialize a date field using the CLEAR operation code in the C-specs. The default initialization and CLEAR value is not all zeros, as might be expected. For date fields, the default value is January 1, 0001; for time fields, the default value is midnight; and for timestamp fields, the default value is midnight on January 1, 0001. In all cases, the format includes separator characters and is based on the DATFMT and TIMFMT parameters or the default *ISO format. If the DATFMT and TIMFMT keywords are not specified in either the H-spec or the D-spec, the cleared value of a date field is 0001-01-01; the cleared value of a time field is 00.00.00; and the cleared value of a timestamp field is 0001-01-01- 00.00.00.000000. The value set by *LOVAL is the same as the CLEAR value.
The value set by *HIVAL is December 31, 9999 for a date field, one second before midnight (23.59.59) for a time field, and one microsecond before midnight on December 31, 9999 for a timestamp field (9999-12-31- 23.59.59.999999).
Comparing Date Fields
Date data types can be used in factor 1 and factor 2 for many ILE RPG operation codes. As with other types of fields, you can compare date fields only if they have the same data type-date, time or timestamp. ILE RPG will automatically handle different formats-an *ISO-format time field with a value of 15.30.00 will compare equal to a *USA-format time field with a value of 03:30 PM. In the same respect, a *MDY-format date field with a value of 12/16/94 will compare equal to a *YMD-format date field with a value of 94/12/16.
Date Arithmetic
Arithmetic operations are where the new date data types really shine. Many RPG/400 programs use a complex subroutine that accounts for leap years and the varying number of days in each month to calculate the difference between two dates or to increment a date by a specific number of days. You can get the same results with much less effort using date fields and several new operation codes.
The Add Duration (ADDDUR) operation code can be used to add a duration to a date, time or timestamp field, resulting in a field of the same type. Factor 1 is optional and, if not specified, defaults to the result field. Factor 1 and the result field must be the same data type.
Factor 2 is required and contains two parts separated by a colon (:). The first part must be a numeric field, array element or constant with zero decimal positions. The second part is a code indicating the type of duration. The duration code must be valid for the data type of the field specified in the result field. For example, you cannot add a minute duration to a date type field.
The valid duration codes are *YEARS or *Y; *MONTHS or *M; *DAYS or *D; *HOURS or *H; *MINUTES or *MN; *SECONDS or *S; and *MSECONDS or *MS.
An error indicator can be specified in the less-than columns (73-74). The value of the result field remains unchanged and this indicator is set on if:
o The date, time or timestamp field in factor 1 contains invalid data. o Factor 1 is not specified and the date, time or timestamp field in the result field contains invalid data. o The result of the operation is invalid.
3 shows some samples of using the ADDDUR operation code. Since no H-spec is present, all date and time values are specified in *ISO format.
Figure 3 shows some samples of using the ADDDUR operation code. Since no H-spec is present, all date and time values are specified in *ISO format.
The first C-spec adds 30 days to the field start_date and stores the result in the field end_date. Both start_date and end_date are defined as date fields with an *ISO format and an implied length of 10. Since the field start_date is initialized to 1994-12-16, the field end_date will have a value of 1995-01-15 after execution of the ADDDUR operation code. If an error occurs, indicator 50 will be turned on. Indicator 50 will be turned off if no error occurs.
In the second sample in 3, one month is being added to the *USA format date field month_end. The field month_end is initialized to a value of 10/31/1994 in D-specs. Adding one month to the month portion of this date would result in an invalid date of 11/31/1994; but the result of the ADDDUR operation is automatically adjusted to the last valid day of the month. The field month_end will have the value 11/30/1994 after execution of the ADDDUR operation code.
In the second sample in Figure 3, one month is being added to the *USA format date field month_end. The field month_end is initialized to a value of 10/31/1994 in D-specs. Adding one month to the month portion of this date would result in an invalid date of 11/31/1994; but the result of the ADDDUR operation is automatically adjusted to the last valid day of the month. The field month_end will have the value 11/30/1994 after execution of the ADDDUR operation code.
In the next example, one year is added to the field employ_dat and the result is stored in the field anniv_dat. The field employ_dat is initialized to a value of 02/29/1992 in D-specs. Adding one year to this date without any adjustment would result in an invalid date of 02/29/1993 since 1993 is not a leap year; but the result of the ADDDUR operation is again automatically adjusted to the last valid day of the month. The field anniv_dat will have the value 02/28/1993 after execution of the ADDDUR operation code.
The next sample demonstrates the use of the ADDDUR operation code with time fields. The first calculation adds three hours to the literal in factor 1, which is set to midnight. The time constant is expressed in *ISO format using a period (.) as a separator character even though the result field end_time is defined in *HMS format using a colon (:) as a separator character. The next two lines of code add 22 minutes and 50 seconds to end_time, giving a result of 03:22:50.
The Subtract Duration (SUBDUR) operation code follows the same rules as ADDDUR to subtract durations from date fields. The result field is required and must be the same data type as factor 1 if factor 1 is specified. Several examples are shown in 4.
The Subtract Duration (SUBDUR) operation code follows the same rules as ADDDUR to subtract durations from date fields. The result field is required and must be the same data type as factor 1 if factor 1 is specified. Several examples are shown in Figure 4.
The SUBDUR operation can also be used to calculate the duration (or difference) between:
o Two dates. o A date and a timestamp. o Two times. o A time and a timestamp. o Two timestamps.
When calculating a duration, both factor 1 and factor 2 must be specified and must contain the same or compatible data types. A date and a timestamp are compatible as are a time and a timestamp. However, ILE RPG will handle any conversion between date or time formats (i.e., a *USA date subtracted from a *ISO date). The result field is also required and contains two parts. The first must be a numeric field, array element or constant with zero decimal positions in which the result will be placed. The second is separated from the first by a colon (:) and must be a valid duration code indicating the type of duration. The result will be negative if the date or time in factor 1 is earlier than the date or time in factor 2.
4 shows some samples of using the SUBDUR operation code. Since DATFMT(*USA) is specified on the H-spec, all date literals must be provided in *USA format. Because TIMFMT(*HMS) is also specified, all time literals must be provided in *HMS format.
Figure 4 shows some samples of using the SUBDUR operation code. Since DATFMT(*USA) is specified on the H-spec, all date literals must be provided in *USA format. Because TIMFMT(*HMS) is also specified, all time literals must be provided in *HMS format.
The first three examples are very similar to the examples for ADDDUR in the previous section. A duration is subtracted from a date, resulting in a new date; if necessary, ILE RPG automatically adjusts the result to a valid date, taking into account leap year and the number of days in each month.
The fourth sample demonstrates the use of the SUBDUR operation code with timestamp fields to determine the difference between two timestamp values. The field start_time is defined as a timestamp field with a value of 1994-05-12- 02.59.40, and the field end_time is defined as a timestamp field with a value of 1994-05-12-03.22.50. Micro-seconds default to all zeros. Since the duration code *SECS is specified on the result field, the field num_sec will have a value of 1,390 seconds after execution of the SUBDUR operation code.
In the last sample, the date field loan_date, which has a value of 12/16/1993, is subtracted from the date field due_date, which has a value of 12/16/2008. Since the duration code *M (months) is specified on the result field, the field num_mon will have a value of 180 months.
EXTRCT Operation Code
The Extract (EXTRCT) operation code can be used to extract a portion of a date field. Factor 1 must be blank. Factor 2 is required and contains two parts separated by a colon (:). The first part must be a date, time or timestamp field. The second part must be a duration code that is valid for the data type of the field specified in the first part of factor 2. For example, you can extract hours from a time or timestamp field but not from a date field.
The result field may be a numeric or character field. Before the EXTRCT operation is executed, the result field is cleared. Numeric result fields are right-justified while character result fields are left-justified.
The first three samples in 5 extract information from the field due_date which is defined as an *ISO format date field and initialized to 2008-12-16. The month is extracted into the character field char_month with a result of '12'. The day is extracted into the character field char_day with a result of '16'. The year is extracted into the numeric field num_year with a result of 1994.
The first three samples in Figure 5 extract information from the field due_date which is defined as an *ISO format date field and initialized to 2008-12-16. The month is extracted into the character field char_month with a result of '12'. The day is extracted into the character field char_day with a result of '16'. The year is extracted into the numeric field num_year with a result of 1994.
The second group of examples uses the field start_time, which is defined as a timestamp field and initialized to a value of 1994-10-22-02.59.40. The month is extracted into the character field char_month with a result of '10', and the hour is extracted into the numeric field num_hour with a result of 2.
Converting Date Formats
The MOVE and MOVEL operation codes can be used to convert date, time and timestamp fields from one data type or format to another. The valid conversions are:
o Date to date, timestamp, character or numeric. o Time to time, timestamp, character or numeric. o Timestamp to date, time, character or numeric. o Character or numeric to date, time or timestamp.
You can use the Move Array (MOVEA) operation code only to move date data type fields to a charactertype field, array or array element.
As with any move operation, when you use one of the MOVE operation codes to convert from one data type to another, the value in factor 2 will be moved to the result field.
Factor 1 is optional and is used to specify the format of factor 2, when factor 2 is not a date data type. Alternatively, factor 1 can be used to specify the format of the result field when the result field is not a date data type. All of the date formats are valid and, in addition, *JOBRUN can be used to indicate that the date format values from the job should be used. If factor 1 is not specified, then the DATFMT and TIMFMT values in the H-spec are used if specified; otherwise, *ISO format is assumed. Factor 1 must be blank if both factor 2 and the result field are date data types. In this case, ILE RPG will automatically convert from one date format to another.
When a MOVE operation code is used to convert a character field to a date type field, the character field must include the separators required by the format specified in factor 1. Conversely, when a date field is moved to a character field, the character field will contain separators based upon the format specified in factor 1.
Separators are not permitted when moving a numeric field to a date field, nor are they inserted when moving a date field to a numeric field.
6 shows some samples of converting dates using the MOVE operation code. In the first sample, the field start_num is defined as a zoned decimal field in which we are storing a date in YYMMDD format (941216). We want to add 30 days to the value in start_num. In RPG/400, this requires a subroutine that accounts for leap years and the number of days in each month; but, as 6 illustrates, it is a simple process in ILE RPG.
Figure 6 shows some samples of converting dates using the MOVE operation code. In the first sample, the field start_num is defined as a zoned decimal field in which we are storing a date in YYMMDD format (941216). We want to add 30 days to the value in start_num. In RPG/400, this requires a subroutine that accounts for leap years and the number of days in each month; but, as Figure 6 illustrates, it is a simple process in ILE RPG.
First, we use the MOVE operation code to convert the zoned decimal field start_num to the *ISO date start_date. Factor 1 indicates the field start_num is in *YMD format (e.g., YYMMDD). Then all we have to do is use the ADDDUR operation code to add 30 days to start_date and MOVE the *ISO date field start_date back to the zoned decimal field start_num. Again, factor 1 indicates the field start_num is to be formatted in *YMD format. The field start_num will have the value 950115.
In the next sample, the move operation code is used to convert a date from *USA to *EUR format. The field usa_date is defined as a *USA-format field with a value of 04/16/1916. The field eur_date is defined as a *EUR-format field. Moving the field usa_date to the field eur_date will result in eur_date having the value 16.04.1916.
The final sample demonstrates a potentially serious problem for those who store their dates in MMDDYY, DDMMYY or YYMMDD format. Dates in these formats must be in the range of 1940 to 2039. Attempting to move a value outside of this range to this format date will result in a run-time error. Since the *USA-format date usa_date has a value of 04/16/1916, which is before 1940, attempting to move this date to the *YMD-format date ymd_date will cause a run-time error.
Many people store their dates in packed decimal fields in CYYMMDD format where C represents the century (e.g., 0941216 represents 12/16/1994 and 1941216 represents 12/16/2094). *CYMD is not currently supported as a convert-from or convert-to date format. This is one of the most serious deficiencies in the ILE RPG language definition. Hopefully, IBM Toronto will recognize the major problems this will cause. Hopefully, this support will be added to ILE RPG before general availability of V3R1M0 or, worst case, be made available in the next release (or version?).
Summary
In this series of articles, we've only had time to take a look at some of the enhancements IBM has made to RPG in V3R1M0. For example, we haven't covered bound program calls; CLEAR and RESET operation code enhancements; date, time and timestamp built-in functions; and much more. Yet, we have seen that ILE RPG has introduced many radical changes to the RPG language definition:
o Numerous modifications were required to handle the change from 6- to 10- character symbolic names.
o Keyword notation has not only freed up space to accommodate longer fields in F-specs, it has also made the coding of H-specs and F-specs much easier for us and much easier for IBM to enhance in the future.
o E-specs have been eliminated with array and table definition moved to D- specs. Named constant and data structure definition has been moved from I-specs to D-specs.
o The new D-specs permit us to consolidate our data definitions in a single place in our programs. Substantial productivity gains should result from the introduction of the OVERLAY and PREFIX keywords and the ability to use length notation in data structures.
o Major changes to C-specs include six-character operation codes and free-form arithmetic and logical expressions. Our programs should be easier to code and maintain with the ability to code complex logic in a single EVAL, IF, WHEN, DOW or DOU calculation continued over multiple lines as necessary.
o Built-in functions can substantially reduce program development and maintenance time, in some cases reducing complex routines or called programs in RPG/400 to a single line of code in ILE RPG.
o The introduction of date, time and timestamp data types will finally let us easily address the year 2000. The ADDDUR and SUBDUR operation codes will enable us to replace entire subroutines or subprograms with a single line of code. ILE RPG is not the same old RPG. It offers the hope of making RPG a viable language into the twenty-first century.
Charlie Massoglia, president of Massoglia Technical Consulting, Inc. in Okemos, Michigan, has authored a number of midrange books. His cowboy hat is his trademark for his frequent speaking tours throughout the United States, Canada, Europe and Australia. Charlie can be reached at 517-676-9700.
Date, Time and Timestamp Data Types
DDS has supported date, time and timestamp data types for some time. Because these data types are not directly supported in RPG/400, they have been of little practical value for RPG programmers. ILE RPG is about to change that.
A1 shows the eight date formats currently supported for date fields. The date format controls the order and length of the month, day and year. In addition, the date format specifies the default separator character of slash (/), hyphen (-) or period (.). The year can be represented in two-byte (yy) and four-byte (yyyy) character format. The day of month (dd) is represented in two- byte format, while Julian day (ddd) is represented in three-byte format. The month (mm) is always represented in two-byte format.
Figure A1 shows the eight date formats currently supported for date fields. The date format controls the order and length of the month, day and year. In addition, the date format specifies the default separator character of slash (/), hyphen (-) or period (.). The year can be represented in two-byte (yy) and four-byte (yyyy) character format. The day of month (dd) is represented in two- byte format, while Julian day (ddd) is represented in three-byte format. The month (mm) is always represented in two-byte format.
The external length is the number of bytes of storage required to store the date field on disk without the separator characters. All date fields, regardless of date format, require four bytes of storage. The internal length is the number of bytes of storage required to represent the date in a program, on a screen or in a report including the separator characters. Date fields require between six and ten characters of storage for internal representation, depending upon the date format specified.
Leading zeros are required for all date formats except *USA.
ILE RPG supports five time formats, as shown in A2. The time format designates whether 12- or 24-hour format is used and whether seconds are shown. In addition, the time format specifies the default separator character of colon (:) or period (.). Hours (hh) and minutes (mm) are represented in two-byte format. Either the seconds (ss) are represented in two-byte format for 24-hour time, or AM or PM is represented in two-byte format for 12-hour time.
ILE RPG supports five time formats, as shown in Figure A2. The time format designates whether 12- or 24-hour format is used and whether seconds are shown. In addition, the time format specifies the default separator character of colon (:) or period (.). Hours (hh) and minutes (mm) are represented in two-byte format. Either the seconds (ss) are represented in two-byte format for 24-hour time, or AM or PM is represented in two-byte format for 12-hour time.
The external length of a time field is always three bytes. Time fields always require eight bytes for internal representation regardless of the time format specified.
Leading zeros are required for all time formats except *USA.
Fields with a timestamp data type always have the same format as shown in A3. Year (yyyy) is always four bytes, followed by month (mm), day (dd), hours (hh), minutes (mm) and seconds (ss) which are always two bytes. Microseconds (uuuuuu) is last with six bytes. The separator characters are always a combination of hyphens (-) for the date and periods (.) for the time.
Fields with a timestamp data type always have the same format as shown in Figure A3. Year (yyyy) is always four bytes, followed by month (mm), day (dd), hours (hh), minutes (mm) and seconds (ss) which are always two bytes. Microseconds (uuuuuu) is last with six bytes. The separator characters are always a combination of hyphens (-) for the date and periods (.) for the time.
The external length of a time-stamp field is always 10 bytes. Timestamp fields always require 26 bytes for internal representation. If microseconds is not specified when a timestamp value is used in ILE RPG, the compiler pads the value with zeros.
An Introduction to ILE RPG: Part 5
Figure 1 Defining Date and Time Fields with Initialized Val
Format *.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10 HFunctions+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Comm ents++++++++++++ H DName+++++++++++ETDsFrom+++To/L+++IDc.Functions............................Comm ents++++++++++++ D eur_date S D DATFMT(*EUR) INZ(D'1994-12-16') 16.12.1994 D usa_date S D DATFMT(*USA) INZ(D'1994-12-16') 12/16/1994 D iso_date S D INZ(D'1994-12-16') 1994-12-16 D hms_time S T TIMFMT(*HMS) INZ(T'18.06.30') 18:06:30 D usa_time S T TIMFMT(*USA) INZ(T'18.06.30') 6:06 PM D iso_time S T INZ(T'18.06.30') 18.06.30
An Introduction to ILE RPG: Part 5
Figure 2 Defining Date and Time Fields with Initialized Val
*HMS Format *.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10 HFunctions+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Comm ents++++++++++++ H DATFMT(*USA) TIMFMT(*HMS) DName+++++++++++ETDsFrom+++To/L+++IDc.Functions............................Comm ents++++++++++++ D eur_date S D DATFMT(*EUR) INZ(D'12/16/1994') 16.12.1994 D eur_date2 S LIKE(eur_date) INZ(D'05/18/1995') 18.05.1995 D usa_date S D DATFMT(*USA&) INZ(D'12/16/1994') 12 16 1994 D usa_date2 S D INZ(D'12/16/1994') 12/16/1994 D iso_date S D DATFMT(*ISO) INZ(D'12/16/1994') 1994-12-16 D usa_time S T TIMFMT(*USA) INZ(T'18:06:30') 6:06 PM D hms_time S T INZ(T'18:06:30') 18:06:30 D iso_time S T TIMFMT(*ISO) INZ(T'18:06:30') 18.06.30
An Introduction to ILE RPG: Part 5
Figure 3 ADDDUR-Add Duration Operation Code
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10 DName+++++++++++ETDsFrom+++To/L+++IDc.Functions............................Comm ents++++++++++++ D start_date S D DATFMT(*ISO) INZ(D'1994-12-16') D end_date S D DATFMT(*ISO) D month_end S D DATFMT(*USA) INZ(D'1994-10-31') D employ_dat S D DATFMT(*USA) INZ(D'1992-02-29') D anniv_dat S D DATFMT(*USA) D end_time S T TIMFMT(*HMS) D total_time S Z CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len++D+HiLoEq....Comm ents+++++++++++++ * * Add 30 days to date * C start_date adddur 30:*days end_date 50 * * Add 1 month to date * C adddur 1:*months month_end * * Add 1 year to date * C employ_dat adddur 1:*years anniv_dat * * Add 3 hours, 22 minutes and 50 seconds to midnight * C T'00.00.00' adddur 3:*hours end_time C adddur 22:*min end_time C adddur 50:*seconds end_time * * Add 1000 microseconds to a timestamp * C adddur 1000:*ms total_time
An Introduction to ILE RPG: Part 5
Figure 4 SUBDUR-Subtract Duration Operation Code
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10 HFunctions+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Comm ents++++++++++++ H DATFMT(*USA) TIMFMT(*HMS) DName+++++++++++ETDsFrom+++To/L+++IDc.Functions............................Comm ents++++++++++++ D start_date S D DATFMT(*ISO) D end_date S D DATFMT(*ISO) INZ(D'01/04/1995') D month_end S D DATFMT(*USA) INZ(D'10/31/1994') D employ_dat S D DATFMT(*USA) D anniv_dat S D DATFMT(*USA) INZ(D'02/29/1992') D start_time S Z INZ(Z'1994-05-12-02.59.40') D end_time S Z INZ(Z'1994-05-12-03.22.50') D loan_date S D INZ(D'12/16/1993') D due_date S D INZ(D'12/16/2008') CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len++D+HiLoEq....Comm ents+++++++++++++ * * Subtract 30 days from date * C end_date subdur 30:*days start_date 50 * * Subtract 1 month from date * C subdur 1:*months month_end * * Subtract 1 year from date * C anniv_date subdur 1:*years employ_dat * * Calculate number of seconds between start and stop timestamps * C end_time subdur start_time num_sec:*secs 7 0 * * Calculate number of days between dates * CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len++D+HiLoEq....Comm ents+++++++++++++ C due_date subdur loan_date num_mon:*m 3 0
An Introduction to ILE RPG: Part 5
Figure 5 EXTRCT-Extract Operation Code
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10 DName+++++++++++ETDsFrom+++To/L+++IDc.Functions............................Comm ents++++++++++++ D due_date S D INZ(D'2008-12-16') D start_time S Z INZ(Z'1994-10-22-02.59.40') CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len++D+HiLoEq....Comm ents+++++++++++++ * * Extract month, day and year * C extrct due_date:*m char_month 2 C extrct due_date:*d char_day 2 C extrct due_date:*y num_year 4 0 * * Extract month and hours * C extrct start_time:*m char_month C extrct start_time:*h num_hour 2 0
An Introduction to ILE RPG: Part 5
Figure 6 MOVE with Dates, Times and Timestamps
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10 * No H-spec so dates and times default to *ISO format. DName+++++++++++ETDsFrom+++To/L+++IDc.Functions............................Comm ents++++++++++++ D start_num S 6S 0 INZ(941216) D start_date S D DATFMT(*ISO) D usa_date S D DATFMT(*USA) INZ(D'1916-04-16') 04/16/1916 D eur_date S D DATFMT(*EUR) D ymd_date S D DATFMT(*YMD) CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len++D+HiLoEq....Comm ents+++++++++++++ * * Add 30 days to date stored as a number in YYMMDD format * C *YMD move start_num start_date start_date=1994-12-16 C adddur 30:*days start_date start_date=1995-01-15 C *YMD move start_date start_num start_num=950115 * * Convert a date from *USA to *EUR format * C move usa_date eur_date eur_date=16.04.1916 * * Cannot convert a date before 1940 or after 2039 to *YMD format * C move usa_date ymd_date run time error
An Introduction to ILE RPG: Part 5
Figure A1 Date Formats and Default Separators
Date Format Date Format Internal External Parameter Description and Separator Length Length Example *MDY Month/Day/Year mm/dd/yy 8 4 12/16/94 *DMY Day/Month/Year dd/mm/yy 8 4 16/12/94 *YMD Year/Month/Day yy/mm/dd 8 4 94/12/16 *JUL Julian yy/ddd 6 4 94/350 *ISO International Standards yyyy-mm-dd 10 4 1994-12-16 Organization *USA IBM USA Standard mm/dd/yyyy 10 4 12/16/1994 *EUR IBM European Standard dd.mm.yyyy 10 4 16.12.1994 *JIS Japanese Industrial yyyy-mm-dd 10 4 1994-12-16 Standard Christian Era
An Introduction to ILE RPG: Part 5
Figure A2 Time Formats and Default Separators
Time Format Time Format Internal External Parameter Description and Separator Length Length Example *HMS Hours:Minutes:Seconds hh:mm:ss 8 3 18:06:30 *ISO International Standards hh.mm.ss 8 3 18.06.30 Organization *USA IBM USA Standard hh:mm AM or 8 3 6:06 PM hh:mm PM *EUR IBM European Standard hh.mm.ss 8 3 18.06.30 *JIS Japanese Industrial hh:mm:ss 8 3 18:06:30 Standard Christian Era
An Introduction to ILE RPG: Part 5
Figure A3 Timestamp Format and Separator Characters
Internal External Format Length Length Example yyyy-mm-dd-hh.mm.ss.uuuuuu 26 10 1994-12-16.18.06.30.000001
LATEST COMMENTS
MC Press Online