DATE, TIME, and DATETIME Fields

This chapter shows you how you can use DATE, TIME, and DATETIME fields in assignments, ACCEPT (validation), PRINT and SEND statements (Display).

DATE, TIME, and DATETIME Fields. 1

Introduction. 1

Section 1.  DATE fields. 2

Assignment To DATE Fields. 2

Assignment From DATE Fields. 3

Validating DATE Data. 3

Section 2.  TIME fields. 4

Section 3.  DATETIME fields. 4

Text Conventions. 5

 

Introduction

A field may be defined with type DATE, TIME, or DATETIME: -

DEFINE W DATA(

    Date1 DATE DPIC 'dd-MMM-yy',

    Date2 DATE DPIC 'dd.mmmm.yyyy',

    Date3 DATE DPIC 'dd/mm/yy',

    Date5 DATE DPIC 'yyyy.ddd',

    Date6 DATE DPIC 'ddd/yy',

    SpecialDate DATE VALUE 19631122);

    Time1 TIME,

    DateTime1 DATETIME );

 

By defining fields like this you make it clear to others, and to Jazz, the type of data that is in these fields: what it is used for, what values are valid, and how it should be displayed.   Jazz can ensure that it is set validly: for example

DEFINE X DATA(Date5 CHAR(9));

ACCEPT(W.Date5 = X.Date5) MESSAGE(Err.Msg);

will report an error if the CHAR(9) value in X.Date5 is not a valid date in format 'yyyy.ddd', such as 2016.060.

 

DATE and TIME fields are internally the same as INTEGER fields, in COBOL PIC S9(9) COMP, with initial value ZERO which means “No DATE (or TIME) value”  A DATETIME field is a combination: you can think of it as either a BIGINT field, or a GROUP containing a DATE and a TIME field. 

 

Whatever the DPIC (Display PICture), data in a DATE field is always stored as 8 digits: four year digits, two month, and two day.  Thus with value 2016.060 in X.Date5, W.Date5 is set to 20160229 (2016 is a leap year).

 

Refer to JazzLRM_Data.#Display_Options for information about DPIC.

 

TIME and DATETIME fields are not implemented yet, except for definition. TIME data will be stored as 9 digits: 2 for hour (00 to 23), 2 for minute (00 to 59), 2 for seconds (00 to 59), and 3 for milliseconds.

Section 1.  DATE fields

Assignment To DATE Fields.

A DATE field may be set from

·         Another DATE field

 

·         A constant.   If you set a DATE field from a constant, then Jazz will interpret and validate the value when your program is checked, according to these rules: -

·         Numeric constants.  For example: -

W.Date1 = 20160228;

 

The value is in order year, month, and day no matter what DPIC is used.  You can give separator characters between year, month, and day if you like, for example

W.Date1 = 2016/2/29;

If there is only a single separator character then the value is interpreted as a Julian date, with the part before the separator (usually “.”) being interpreted as century and year if 4 digits, or year if two, and the part after the separator being interpreted as the day value from 1 to 365 (366 if a leap year).  Thus

W.Date1 = 2017.6;

or         W.Date1 = 2017.06; or W.Date1 = 2017.006;

is interpreted as 20170106,

W.Date1 = 2017.60;

is interpreted as 20170301, and

W.Date1 = 2016.60;

as 20160229.   If the century is omitted, as in

W.Date1 = 18.60;

then the current century is used, making this 20180301

 

The date value is validated: for example: -

W.Date1 = 20170229;  [Not a leap year

#568 E Date Value invalid: Day Invalid

To reset a date to its initial value, or to zero indicating that the field contains no date, use

W.Date1 = JAZZ.$Init;

or

W.Date1 = JAZZ.$Null;

(You’ll simply write $Init or $Null, leaving it to Jazz to insert the qualification)

 

·         String constants. With a string value the value is checked using the DPIC, for example

Date1 DATE DPIC 'dd-MMM-yy', …

W.Date1 = '27 May 17';

With this DPIC Jazz logic checks that characters 1-2 are a number from 01 to the maximum for the month, characters 4-6 are one of the known three-character month abbreviations, and characters 8-9 are a number from 00 to 99.  Jazz doesn’t care if the separator character is the same as in the DPIC, but there must be one character between each section.   Note that leading zeros are required.

 

Because the string value is interpreted by DPIC, not by “what is obvious”, so that with the DPIC above and this assignment

W.Date1 = '2017/02/28';

Jazz interprets 20 as the day, 7/0 as the month name, and “/2” as the year, leading to error messages: -

#568 E Date Value invalid: Year '/2' not numeric

#568 E Date Value invalid: Month '7/0' invalid

 

·         A numeric or string (CHAR or VARCHAR) variable.   When assigning data from another type you should use an ACCEPT statement unless you are certain that the source data is correctly formatted for the assignment type.   ACCEPT will check the input using the same rules as above, giving you error notifications when the data is invalid.

Assignment From DATE Fields.

A DATE field may be assigned to

·         Another DATE field

·         A numeric variable

Assigning a DATE to a number will assign an eight-digit numeric value such as 20180124.  A message will be produced if the numeric variable has fewer than 8 digits.  If the target number has a suitable DPIC then the value will be easy to interpret: for example

DEFINE X DATA(Number INTEGER DPIC '9999,99,99');

DEFINE W DATA(Date1 DATE DPIC 'dd-MMM-yy');

X.Number = W.Date1;

PRINT (W.Date1, X.Number);

resulting in output like this: -

*-Date1-* *-Number-*

29-Feb-16 2016,02,29

 

·         A CHAR or VARCHAR variable.  The date field will be formatted to a string according to its DPIC.  For example: -

DEFINE W DATA(

    Date2 DATE DPIC 'dd.MMMM.yyyy');

DEFINE X DATA(

    Date2 CHAR(17);

W.Date2 = 20171217;

X.Date2 = W.Date2;

assigns value '17.December.2017' to X.Date2.

 

Refer to JazzLRM_Data.#Display_Options for information about DPIC.

Validating DATE Data

When variable data is assigned to a DATE field it is recommended that you use ACCEPT, rather than a simple assignment, as this will validate that the assigned data is actually a date, setting $Error and producing messages when the source field cannot be converted to a valid date.  Refer to JazzLRM_Accept for more information about ACCEPT.  As with any other ACCEPT statement, several validations and assignments may be combined into one statement: -

ACCEPT(W.Date1 = X.Date1, W.Date5 = X.Date5) MESSAGE(Err.Msg);

and assignment targets (W.Date1, W.Date5 in the example above) may be omitted if the target is implied or there’s no assignment because a DATE field is being validated in place.

Character input

If the source fields (X.Date1, X.Date5 in the example above) have type CHAR or VARCHAR then if possible their value is converted into an eight-digit number using the DPIC of the target field.  The positions of year, month, and day sections is the same as their positions in the DPIC except that code MMMM, meaning the full month name, implies 8 characters, not 4, so that with DPIC 'dd.MMMM.yyyy' the year value will be in positions 12-15.

 

Separator characters (“ ”, “.”, “/”, “,”) are counted but not checked: for example there must be one character between the day and the month with this DPIC, but it doesn’t have to be a period.

 

First the year is obtained.  If the year format is given as yy then a value from 01 to 99 is expected, and today’s century will be used.  The year, either as 2 or 4 digits, must be numeric.  Leading zeros are required: “01”, not “1b”.  From the year value it can be determined whether this is a leap year.

 

For DPICs with month, the month value is obtained by: -

·         DPIC MM: a numeric value from 01 to 12 is expected.  Leading zeros are required.

·         DPIC MMM: a short (3 character) month name, “Jan”, “Feb” … “Dec” is expected.  Jazz looks up JZSMth.SMTH to find this.

·         DPIC MMMM: a full (8 character) month name, “January”, to “December” is expected.  Jazz looks up JZLMth.LMTH to find this.

·         The Day value must be a numeric value from 01 to the maximum for the month: 30 or 31 except for February, whose maximum is 29 in leap years, otherwise 28

 

For Julian DPICs the day value is 001 to 365 (or 366 for a leap year), and the month is calculated from the day.

Numeric Input

A number is first range-checked: it must not be less than 10000101  (1 Jan 1000) or greater than 99991231  (31st December 9999).  If it survives this check, then the value of Month (digits 5-6) and Day (7-8) are checked as above.

Date Arithmetic

Not yet implemented.  It is intended to provide $Year, $Month, and $Day built-in functions to extract the various sections of a DATE value, and provide the following arithmetic operations: -

            Date1 = Date2 +|- Number {Days | Months | Years};

            Date1 = Date2 +|- Date3;

            Number = Date2 +|- Date3 {Days | Months | Years};

plus equivalent forms like

            Date1 += Number {Days | Months | Years};

Other arithmetic operators won’t be provided.

Date Logic

DATE fields can be used in comparisons.  All the usual comparison operators, =, <>, >, >=, <, <=, are available.

Section 2.  TIME fields

Not yet implemented, except for definition.  TIME data will be stored as 9 digits: 2 for hour (00 to 23), 2 for minute (00 to 59), 2 for seconds (00 to 59), and 3 for milliseconds.   

 

As with DATE fields, assignment of constant data will be validated by Jazz when the program is checked, and variable data can be validated with ACCEPT. 

 

DPIC formats for TIME data will be defined. 

 

Built-in functions $Hour, $Minute, $Second, and $MSecond will extract the various parts of a time.

 

TIME arithmetic will be supported: details to be defined.

 

Section 3.  DATETIME fields

Not yet implemented, except for definition.  A DATETIME field is like a GROUP defined

    DTGroup GROUP,

        DatePart DATE,

        TimePart TIME,

        end GROUP);

except that adding or subtracting time from Timepart does not affect Datepart, whereas adding or subtracting time from a DATETIME field can change the date part of the DATETIME field.

 

Assignment between DATETIME and DATE or TIME fields is permitted: -

·         Datetime = Date;   Datepart set, Timepart is set to 00:00:00:000

·         Datetime = Time;   Date set to 0, Timepart set.  E-level message

·         Datetime &= Time; Datepart unchanged, Timepart set.

·         Date = Datetime;  Datepart is assigned, Timepart ignored

·         Time = Datetime;  Timepart is assigned, Datepart ignored.

Text Conventions  

Some material is like this, written in the normal text, but coloured green. This is material that hasn’t been implemented yet. As this material is implemented the text is reviewed, changed as necessary, and changed to normal text colour.