DATE Directive

The DATE directive instructs the runtime to store a field in the database as a date or a time. Because there's no COBOL syntax that identifies a field as a date or time, you may want to add this directive to differentiate dates or times from other numbers, so that they enjoy the properties associated with dates or times in the RDBMS.

Syntax

$XFD DATE=date-format-string

or

*(( XFD DATE=date-format-string ))

The date-format-string is a description of the desired date or time format in the COBOL program, composed of characters from the following list:

M     month (01 – 12)
Y year (2 or 4-digit)
D day of month (01 – 31)
J Julian day (00000000 – 99999999)
E day of year (001 – 366)
H hour (00 – 23)
N minute
S second
T hundredths of a second

Any other characters cause the date-format-string to be invalid and result in a corrupt XFD error or a compile-time warning.

Each character in a date-format-string can be considered a place holder that represents the type of information stored at that location. The characters also determine how many digits will be used for each type of data.

For example, although you would typically represent the month with two digits, if you specify MMM as part of your date format, the resulting date will use three digits for the month, left-zero-filling the value. If the month is given as M, the resulting date will use a single digit and will truncate on the left.

If you do not specify a date-format-string, the default is YYMMDD if the field has six digits, or YYYYMMDD if the field has eight digits.

Julian dates

Because the definition of Julian day varies, the DATE directive offers a great deal of flexibility for representing Julian dates. Many source books define the Julian day as the day of the year, with January 1st being 001, January 2nd being 002, and so forth. If you want to use this definition for Julian day, simply use EEE (day of year) in your date formats.

Other reference books define the Julian day as the number of days since some specific "base date" in the past. This definition is represented in the DATE directive with the letter "J" (for example, a six-digit date field would be preceded with the directive "$XFD DATE=JJJJJJ"). The default "base date" for this form of Julian date is 12/31/4714 BC.

You may define your own base date for Julian date calculations by setting the runtime configuration variable 4GL-JULIAN-BASE-DATE. The value of this variable must have the format YYYYMMDD. For more information, see the Acu4GL User's Guide.

Using group items

You may place the DATE directive in front of a group item, as long as you also use the USE GROUP directive (see Example 2, below).

Example 1

$xfd date
    03 date-hired     pic 9(8).
    03 pay-scale      pic x(3).

The column date-hired will have eight digits and will be type DATE in the database, with a format of YYYYMMDD.

Example 2

*(( XFD DATE, USE GROUP ))
    03  date-hired.
      05   yyyy    pic 9(4).
      05   mm      pic 9(2).
      05   dd      pic 9(2).

This also will produce a column named date-hired with eight digits and type DATE in the database, format YYYYMMDD.

Example 3

*(( XFD DATE=EEEYYYY))
    03  date-sold      pic 9(7).
    03  sales-rep      pic x(30).

This will produce a column named date-sold with seven digits and type DATE in the database. The date will contain the day of the year (for example, February 1st would be 032), followed by the four-digit year, such as 1999.

Example 4

Note: This format and data type is only applicable with SQL Server, and only when using the SQL Server Native Client 11.0 (or later) ODBC driver.
$XFD DATE=HHNNSSTTT
   03 trans-time pic 9(9).

This produces a column named trans-time containing data items of type TIME. The time is represented down to the hundredths of a second (for example, 123030030 represents a time of 12:30:30.03).

FY and RY date formats

The FH and RY date format characters have very precise requirements and are used to handle a specific case in which eight-digit dates are expressed in six characters.

Instead of YYYY or YY, you can specify FY to mean that the first character of the year specifies the decade instead of the "tens" year. The decade can be a character between space (" ") and "I" (inclusive). For the characters "0" through "9" to be treated as decades in the 20th century, the decade characters have the following meaning:

  00 10 20 30 40 50 60 70 80 90
1700         spc ! " # $ %
1800 & ' ( ) * + , - . /
1900 0 1 2 3 4 5 6 7 8 9
2000 : ; < = > ? @ A B C
2010 D E F G H I        

This means that a date of ?70210 is converted to 20570210, or February 10, 2057. The range of valid dates is 00101 (Jan 1, 1740) through I91231 (Dec 31, 2159).

Instead of YYYY or YY, you can also specify RY to mean that the first character of the year specifies the decade and that the entire date is to be 9s complement (to be able to sort dates in reverse order). Note that the entire date and time is treated as a 9s complement number in this case. The decade characters have the following meaning:

  00 10 20 30 40 50 60 70 80 90
1700         I H G F E D
1800 C B A @ ? > = < ; :
1900 9 8 7 6 5 4 3 2 1 0
2000 / . - , + * ) ( ' &
2010 % $ # " ! spc        

The date 20570210 is now specified with *29789. The range of valid dates is I99898 (Jan 1, 1740) through 08768 (Dec 31, 2159), the same valid range as when using F instead of R.

While using F and R before month, day, hour, or any other format specifier does not generate a compile error for the XFD, the results are undefined at run time.

Note that if you use these format specifiers with Acu4GL, the actual date is written to the database, not the encoded date. This means that the R specifier is not very useful in this scenario (you won't be able to read forward through a file in reverse date order). This format specifier is more useful with AcuXDBC, where the data is in indexed file format.