ILE COBOL Programmer's Guide

MOVE Considerations for Date-Time Data Items

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:

Translation of @p to Uppercase

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

Conversion of 2-Digit Years to 4-Digit Years or Centuries

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:

Note:
When an alphanumeric data item containing a date is moved to a date-time data item, no checking or conversion is done. The programmer must ensure that the alphanumeric date being moved is in the correct format.

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.

Overriding the Default Date Window Using the DATTIM Process Statement Option

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--)-------><
 
 

4-digit base century
This must be the first argument. Defines the base century that ILE COBOL uses for its windowing algorithm. If the DATTIM process statement option is not specified, 1900 is used.

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.

2-digit base year
This must be the second argument. Defines the base year that ILE COBOL uses for its windowing algorithm. If the DATTIM process statement option is not specified, 40 is used.

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).

Performance Considerations for Date-Time Relational Conditions

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.

Performance Considerations for Date-Time MOVEs

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:

  1. A date-time item whose format is equivalent to an iSeries DDS supported date, time, or timestamp format. Within this group, ISO formats are generally the best.
  2. A non-locale based date-time item whose format is not part of 1.
  3. A locale-based date-time item.

Conversion of Times to Microseconds

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:

@Sh
Hundredths of a second

@Sm
Millionths of a second (microseconds)

@So
Thousandths of a second (milliseconds)

@St
Tenths of a second

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.

Time Zones

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.


[ Top of Page | Previous Page | Next Page | Table of Contents | Index ]