This section describes some of the considerations for using date-time data items in the MOVE statement and, statements where there is an implicit move (READ INTO, WRITE FROM, REWRITE FROM, RETURN INTO, and RELEASE FROM), and relation conditions:
Time items can be defined with the @p conversion specifier. This specifier will be replaced with either AM or PM. However, the AM and PM can be any mix of upper and lower case characters. This means that in a statement that contains both source and receivers with the @p conversion specifier, the source can contain a mix of upper and lower case characters, but the receiver will always be translated into upper case characters. For example:
01 group-item. 05 time1 FORMAT TIME "%I:%M @p" VALUE "06:20 am". 05 time2 LIKE time1. MOVE time1 TO time2. DISPLAY "time2 = " time2.
In the above code, time1 is the source for the MOVE statement, so its @p specifier can be a mix of upper and lower case, in this example it is lowercase am. The receiver, time2, which has a format identical to time1, will contain @p in upper case. Thus the output of the above program would be:
time2 = 06:20 AM
When you are moving or comparing 2-digit years to 4-digit years or centuries, or comparing 4-digit years or centuries to 2-digit years, ILE COBOL first converts the 2-digit year using a windowing algorithm. The default windowing algorithm used is as follows:
To show you how this works, three date moves are done in this program:
ID DIVISION. PROGRAM-ID. datmoves. ENVIRONMENT DIVISION. CONFIGURATION SECTION. SPECIAL-NAMES. FORMAT DATE IS '%m/%d/%y'. DATA DIVISION. WORKING-STORAGE SECTION. 77 date1 format date Value '07/12/39'. 77 date2 format date '@Y/%m/%d'. 77 date3 format date '%y/%m/%d'. 01 ALPHA_USA_S PIC X(08). PROCEDURE DIVISION. PARA1. move date1 to date2. (1) display "date2 =" date2. * move date2 to date3. (2) display "date3 =" date3. * move FUNCTION ADD-DURATION (date3 YEARS 1) to date2. (3) display "date2 =" date2.
The output from this program is:
date2 =2039/07/12 date3 =39/07/12 date2 =1940/07/12
In move (1), date1 (containing the value 07/12/39) is moved to date2. Because date1 contains a 2-digit year that is less than 40, and it is moved to date2, which has a 4-digit year, the century used is 2000 and the 4-digit year becomes 2039.
In move (2), a 4-digit year is moved to a 2-digit year, and the century (1st 2 digits of the year) is just truncated.
In move (3), a year is added to date3 and it is then moved back to a 4-digit year. Because the year that was added moved the 2-digit year of the date out of the 21st century, the date becomes a 20th century date and is inaccurate. This move shows you how the windowing algorithm works, and how inaccuracies can result when moving dates between 4-digit and 2-digit year formats.
Sometimes you may not be able to avoid moving dates between 4-digit and 2-digit years, and you know that inaccuracy will result based on the default windowing algorithm that ILE COBOL uses. You can use the DATTIM process statement option to change the default date window.
The syntax of the DATTIM process statement is:
Syntax >>-DATTIM--(--4-digit base century--2-digit base year--)-------><
The 4-digit-base-century also affects the interpretation of the @C conversion specifier. The @C conversion specifier represents a 1-digit century, whose value ranges between 0 and 9. A 0 for a 1-digit century represents a base century of 1900, 1 = 2000, ... 9 = 2800. So, a date data item whose format is @C/%y/%m and whose value is 1/12/05, represents year 2012, the first day of month 5 (May). However, 0 of @C is really equal to the 4-digit base century. Thus, a DATTIM(2200, 40) would cause 0 = 2200, 1 = 2300 ..., 9 = 3100.
The default DATTIM(1900, 40) results in a 100-year window of 1940 through 2039. To solve the problem encountered in our previous example, we could set the DATTIM option in either of the following ways:
Given either of these options on a PROCESS statement in the previous example, the output would be:
date2 =2039/07/12 date3 =39/07/12 date2 =2040/07/12
The only change in the output is the result of move (3). If you remember from the previous example, the output was date2 =1940/07/12, which was an inaccurate result from moving an updated 2-digit date to a 4-digit date based on the default ILE COBOL windowing algorithm (base century of 1900 and base year of 40).
When a date-time item is or compared to another date-time item in ILE COBOL, it is first stripped of all separators and converted to ISO format (no separators). The two date-time items are then compared, digit by digit. In the case of a date to date comparison, both dates are converted to @Y%m%d and then compared. Times would be converted to %H%M%S, and then compared. This means that to get the best performance for date-time compares, date-time items should be in ISO format.
The format of a date-time item affects the amount of time a date-time move will take to complete. The three basic formats in order of best to worst performance are:
A time data item can contain one or more specifiers that contain fractions of a second. The four conversion specifiers that hold fractions of a second are:
For example, a time data item might have the format %H:%M:%S @So/@Sm.
If there are two time data items and one is moved to the other, the specifiers that hold fractions of a second in the sending data item are all converted to one number, representing the number of microseconds. The microseconds are then converted to the appropriate fractions of a second in the receiving time data item.
Category time and timestamp data items are affected by time zones. ILE COBOLretrieves time zone information from the iSeries system value QUTCOFFSET (Coordinated Universal Time Offset, also known as Greenwich Mean Time offset), and from LC_TOD locale category. A time data item associated with a locale uses the time zone in the tzdiff keyword of the LC_TOD locale category. A time data item which is not associated with a locale and a timestamp data item are assumed to be in the time zone of the iSeries system. That is, in the time zone specified by the QUTCOFFSET system value.
So, for example:
SPECIAL-NAMES. LOCALE "EN_US" IN LIBRARY "QSYSLOCALE" IS USA.
·
·
·
01 GROUP-ITEM. 05 SYSTEM-TIME-1 FORMAT TIME "%H:%M:%S" VALUE "14:32:10". 05 LOCALE-TIME-1 FORMAT TIME SIZE 8 IS LOCALE USA.
·
·
·
MOVE SYSTEM-TIME-1 TO LOCALE-TIME-1.
The locale source for EN_US that is shipped with an iSeries system has a default tzdiff value of 0. However, this can be changed by the user by copying the locale source to a different source physical file. In the MOVE statement above, the data item SYSTEM-TIME-1 is not associated with any locale, so its time zone is dictated by the QUTCOFFSET system value. The data item LOCALE-TIME-1 is associated with locale EN_US in library QSYSLOCALE. This means that its time zone is dictated by the LC_TOD locale category of this locale. During the MOVE statement, the resulting time in LOCALE-TIME-1 will be adjusted by the difference in the time zones between SYSTEM-TIME-1 and LOCALE-TIME-1.
ILE COBOL does not take into consideration Daylight Savings Time. To accommodate this, you would have to update the Coordinated Universal Time Offset in the LC_TOD locale category and in QUTCOFFSET to account for this time difference.
Other intrinsic functions that take time zones into consideration are: FIND-DURATION, LOCALE-TIME, and CONVERT-DATE-TIME.
(C) Copyright IBM Corporation 1992, 2005. All Rights Reserved.