VARDATE – Generate date and time values from rule

Use the VARDATE command to generate a variable date from a rule.

VARDATE variable|= [BASE(yymmdd|EASTER)] 
                   [CALENDAR(<calendar-name>)]
                   [DAY(ALL|MON|TUE|WED|THU|FRI|SAT|SUN)] 
                   [FORMAT(<format-definition>)]
                   [MONTH(ALL|JAN|FEB|MAR|APR|MAY|JUN|
                     JUL|AUG|SEP|OCT|NOV|DEC|   )]
                   [OFFSET(+n|-n)] [ONLY(n)|LAST(n)]
                   [RULE(BEFORE|AFTER|ON|NEAREST)] [FORMAT(<dateformat>)]
                   [SAVE(YES|NO)] 
                   [SETUP(YES|NO|PROMPT)]
                   [TABLE(table)] [TIME(hhmmss)] [TIME(hhmmss|hhmm)] 
                    [UNIT(DAY|WEEK|MONTH|YEAR|WORKDAY|<day-of-week>)] 
                   [YEAR(nnnn|+n|-n)] [OFFSET(+n|-n)] 

The VARDATE command can either generate a variable, or can be used to set defaults for other VARDATE commands by using the equal sign (=) in place of the variable name.

For example, VARDATE = YEAR(+1) does not create a variable, but makes all subsequent VARDATE commands calculate dates for the following year.

Note:
  1. Even if VARDATE command looks similar to a run cycle rule, it is designed to define only a single date within the specified year.
  2. Because VARDATE is designed to help determine the Free days within the calendar, it does not refer to calendars. For the purposes of calculation, it considers only the differences between weekdays and weekends.
BASE(yymmdd|EASTER)
Provides a base date for setting an OFFSET against. The base date can either be provided in the yymmdd format, either hard coded or from a Workload Automation Programming Language variable, or it can be calculated using a special base name.

Special base names currently include EASTER. This returns the date of Easter Sunday. Defined as the Sunday following the first full moon after the Vernal Equinox, it cannot be easily calculated by VARDATE rules, so a special BASE name is used to access the complex calculation needed.

Note: When you have two consecutive holidays that could be moved by weekends, it is best to use BASE in the second, to reference the variable generated by the first. In this way if the first date moves, the second date does not clash with it. For example:
VARDATE PH_CHRISTMAS ONLY(25) MONTH(DEC) RULE(AFTER)
VARDATE PH_BOXING_DAY BASE(!PH_CHRISTMAS) OFFSET(1) RULE(AFTER)
CALENDAR(<calendar-name>)
Sets the calendar to use if UNIT(WORKDAY) is used.
DAY(ALL|MON|TUE|WED|THU|FRI|SAT|SUN)
Defines which day to count within the calculation period. The default value is ALL, which counts every day in the period.

For example, VARDATE PH-CHRISTMAST ONLY(25) MONTH(DEC) RULE(AFTER) returns 25 December as the primary result, but if that day falls on a weekend it moves it to the following Monday.

If a specific DAY is chosen, the ONLY|LAST count refers only to that type of day. For example, VARDATE PH_THANKSGIVING ONLY(4) DAY(THU) MONTH(NOV) returns the fourth Thursday in November, not the fourth day in November.

FORMAT(<date-format>)
By default, VARDATE returns a date in the native HCL Workload Automation for Z format YYMMDD.
You can use the FORMAT keyword to change the format to an alternative layout by using a combination of the following case sensitive values:
Table 1. Values for the FORMAT keywords
Value Description Example
aa Part of the day in lower case.
  • midnight for exactly 00.00.00
  • am for 00.00.01 – 11.59.59
  • noon for exactly 12.00.00
  • pm for 12.00.01 – 23.59.59
Note: The text is set in the LANGxx file using TERM entries DP00, DPAM, DP12 and DPPM respectively. If you want to provide alternative values, a user language member can be concatenated after the system member to override the supplied value.
pm for 1.05 pm
AA Part of the day in upper case.
  • MIDNIGHT for exactly 00.00.00
  • AM for 00.00.01 – 11.59.59
  • NOON for exactly 12.00.00
  • PM for 12.00.01 – 23.59.59
Note: The text is set in the LANGxx file using TERM entries DP00, DPAM, DP12 and DPPM respectively. If you want to provide alternative values, a user language member can be concatenated after the system member to override the supplied value.
PM for 1.05 pm
CC The century part of the year. 20 for 9 July 2014
D Day of the month with no leading zeros. 9 for 9 July 2014
DD Day of the month with leading zeros. 09 for 9 July 2014
DDD Day of the year (julian day). 190 for 9 July 2014
h Hours in 12 hour format with no leading zeroes. 1 for 1.05 pm.
H Hours in 24 hour format with no leading zeroes. 2 for 2.28 am.
hh Hours in 12 hour format with leading zeroes. 01 for 1.05 pm.
HH Hours in 24 hour format with leading zeroes. 13 for 1.05 pm.
M Month of the year with no leading zeroes. 7 for 9 July 2014
MM Month of the year with leading zeroes. 07 for 9 July 2014
mmm Three character name of the month in mixed case. Jul for 9 July 2014
MMM Three character name of the month in upper case. JUL for 9 July 2014
mmmm Full name of the month in mixed case. July for 9 July 2014
MMMM Full name of the month in upper case. JULY for 9 July 2014
N Minutes with no leading zeroes.
Note: Minutes is NN to avoid conflict with MM for month.
5 for 1.05 pm.
NN Minutes with leading zeroes
Note: Minutes is NN to avoid conflict with MM for month.
05 for 1.05 pm.
OO Ordinal day suffix in upper case. TH for 9 July 2014
oo Ordinal day suffix in lower case. th for 9 July 2013
S Seconds with no leading zeroes. 8 for 1:05:08 pm
SS Seconds with leading zeroes. 08 for 1:05:08 pm
W Day number of the week 1=Monday, 7=Sunday 3 for 9 July 2014
ww Two character name of the day in mixed case. We for 9 July 2014
WW Two character name of the day in upper case. WE for 9 July 2014
WWW Three character name of the day in upper case. WED for 9 July 2014
www Three character name of the day in mixed case. Wed for 9 July 2014
wwww Full name of the day in mixed case. Wednesday for 9 July 2014
WWWW Full name of the day in upper case. WEDNESDAY for 9 July 2014
YY Two digit year. 14 for 9 July 2014
YYYY Four digit year. 2014 for 9 July 2014
MONTH(ALL|JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC| )
Defines the scope of the period to start counting the days from. By default, ALL covers the whole year, therefore ONLY counts from the start of the year and LAST counts from the end of the year. Specifying a month targets the scope to an individual month.
For example:
VARDATE PH_NEW_YEARS_DAY ONLY(1) /* First day of the year */
VARDATE PH_NEW_YEARS_EVE LAST(1) /* Last day of the year */
VARDATE PH_LABOR_DAY ONLY(1) DAY(MON) MONTH(MAY) /* First Monday in May */
VARDATE PH_CHRISTMAS ONLY(25) MONTH(DEC) /* 25th of December */

Specifying MONTH with no value corresponds to the current month, unless you set OPTIONS DATE, in which case it uses the month specified.

For example, VARDATE Q2_W9 ONLY(9) DAY(MON) MONTH(APR) /* 9TH Monday of 2ND Quarter */VARDATE FIRST_MON ONLY(1) DAY(MON) MONTH /* 1ST Monday current month */

Note: Even if the MONTH keyword sets the frame of reference to a particular month, it does not restrict the results to that month. For example, VARDATE Q2_W9 ONLY(9) DAY(MON) MONTH(APR) /* 9TH Monday of 2ND Quarter */
OFFSET(+n|-n)
After the date has been set by either BASE or ONLY|LAST, the OFFSET keyword can be used to move the date backwards or forwards a number of days. For example:
VARDATE MYFRI ONLY(5) DAY(WED) MON(AUG) OFFSET(2) /* FRI after 5th WED */
VARDATE GDFRI BASE(EASTER) OFFSET(-2) /* Good Friday */ 
ONLY|LAST(n)
Used to calculate dates entirely by rules, rather than use a BASE date as the starting point. ONLY refers to a number of days from the start of the calculation period, LAST refers to a number of days from the end of the calculation period.
RULE(BEFORE|AFTER|ON|NEAREST)
After calculation and OFFSET, the date could point to a weekend date. This might not be appropriate if VARDATE is being used to calculate public holidays. The RULE keyword determines what to do with a weekend date:
BEFORE
If the date points to a Saturday or Sunday move the date to the Friday.
AFTER
If the date points to a Saturday or Sunday move the date to the Monday.
ON
Do not adjust the date (default).
NEAREST
If the date points to a Saturday move the date to Friday, if it points to a Sunday move the date to Monday.
SAVE(YES|NO)
The SAVE keyword determines whether and when the variable is written to an HCL Workload Automation for Z JCL variable table:
YES
The variable is written directly in the associated table at this point.
NO
The variable is not written in the associated table, but might be written later if a VARSAVE command is run referencing the table associated to this variable.

If you specify the SAVE keyword with no argument, SAVE(YES) is assumed.

For example, VARSET MYVAR VALUE(Hello World) TABLE(MYTABLE) SAVE
Note: If you want to set several variables to be written to the same table, it is more efficient to use a subsequent VARSAVE command than SAVE on every VARSET.
For example,
VARSET MYVAR1 VALUE(Hello) TABLE(MYTABLE)
VARSET MYVAR2 VALUE(Ciao) TABLE(MYTABLE) 
VARSET MYVAR3 VALUE(Bonjour) TABLE(MYTABLE)
VARSAVE MYTABLE
Note:
  1. Variables do not need to already exist within a table. They are added to the table if needed.
  2. Tables to not need to exist to have variables saved to them. If a table does not exist, it is created automatically, using OPTIONS OWNER to set the Owner ID and the description is set to the creating Job name, Jes Number and current date.
SETUP(YES|NO|PROMPT)
Sets the SETUP value for any new variables when saved into a JCL Variable Table:
YES
Resolve variable at SETUP phase.
NO
Resolve variable at SUBMIT phase (default).
PROMPT
Promptable variable.

The default value can be changed by OPTIONS SETUP.

TABLE(table)
Assigns an HCL Workload Automation for Z JCL Variable Table to a Workload Automation Programming Language variable, so that it can be saved in a JCL Variable Table. If the variable has already been referenced from a JCL Variable Table, the TABLE keyword is not needed. If a Workload Automation Programming Language variable does not have an assigned table name, it cannot be saved.
In the following example, RUNCOUNT might not exist in MYTABLE, but VARFAIL(NULL) will cause the first table in the search sequence at the point to be assigned as the source table name:
VARSUB SCAN(!) TABLE(MYTABLE) VARFAIL(NULL)
VARSET RUNCOUNT VALUE(!RUNCOUNT) DELTA(1) SAVE(YES)

You can however use the TABLE keyword to override the name of the table from which the variable originally came, so the value can be saved to a new table.

TIME(hhmmss) or TIME(hhmm)
Provides the time portion of a variable. The time can be specified in either the format hhmmss or hhmm. If hhmm is used, zero seconds is assumed. If the TIME keyword is not specified, the current time is assumed.
UNIT (DAY|WEEK|MONTH|YEAR|WORKDAY|<day-of-week>|HOURS|MINUTES|SECONDS)
Sets the unit by which the OFFSET is counted:
DAY
Adds or subtracts a number of days (default).
WEEK
Adds or subtracts 7 days per value of OFFSET.
MONTH
Uses the same day of the month using the OFFSET value to move backwards or forwards that number of months. If the resulting month is too short for the origin date, the last day of the month is used.
YEAR
Uses the same day of the month in the resulting year, adjusting 29 February to 28 if necessary.
WORKDAY
Adds or subtracts a number of work days.
Any day of the week
You can also use any day of the week as a UNIT, for exampleMONDAY, such that OFFSET(-1) UNIT(MONDAY) would find the Monday preceding the origin date, and OFFSET(+1) UNIT(MONDAY) would find the Monday following the origin date. If the origin date and the unit are the same day of the week, the offset is seven days.
HOURS
Adds hours to the time portion of the date.
MINUTES
Adds minutes to the time portion of the date.
SECONDS
Adds seconds to the time portion of the date.
YEAR(yyyy|+n|-n)
Sets the year for which the date is calculated. By default, it uses the current Workload Automation Programming Language Date, but can be set it to an individual year, or a relative year. The YEAR keyword is most effectively used by setting the default relative to the running job; in this way the same job can run annually to calculate sets of dates for each year. For example, VARDATE = YEAR(+1) /* Calculate dates for next year */
Note: BASE is mutually exclusive from the ONLY|LAST DAY|MONTH approach. The YEAR keyword is relevant to both approaches, because the year affects Special Base Name resolution as well as DAY|MONTH calculations.

Workload Automation Programming Language is provided with some members containing rule definitions for public holidays for some countries. Look for members in the SEQQWAPL library for members beginning with DATE and a two character country code. These members can be used in conjunction with INCLUDE to define a job to update elements in the database annually with public holidays.

OPTIONS DBMODE(UPDATE)

The following example shows an annual job to maintain calendars with public holidays. The member DATEIT generates variables, which can be referenced in Batch Loader as required:
VARDATE = YEAR(+1) /* Generate dates for next year */
INCLUDE EQQFILE(DATEIT) /* Generates Italian holiday variables */
CLSTART CALENDAR(FESTIVI) DESCR(GIORNI FESTIVI PER L'ITALIA) 
        DROP(-365) /* Drop days over a year old */
CLDAY DAY(MONDAY) STATUS(W) DESCR(GIORNATA DI LAVORO) 
CLDAY DAY(TUESDAY) STATUS(W) DESCR(GIORNATA DI LAVORO) 
CLDAY DAY(WEDNESDAY) STATUS(W) DESCR(GIORNATA DI LAVORO) 
CLDAY DAY(THURSDAY) STATUS(W) DESCR(GIORNATA DI LAVORO) 
CLDAY DAY(FRIDAY) STATUS(W) DESCR(GIORNATA DI LAVORO) 
CLDAY DAY(SATURDAY) STATUS(F) DESCR(GIORNO LIBERO) 
CLDAY DAY(SUNDAY) STATUS(F) DESCR(GIORNO LIBERO) 
CLDATE DATE(!GF_CAPODANNO) STATUS(F) DESCR(CAPODANNO) 
CLDATE DATE(!GF_EPIFANIA) STATUS(F) DESCR(EPIFANIA) 
CLDATE DATE(!GF_PASQUA) STATUS(F) DESCR(PASQUA) 
CLDATE DATE(!GF_PASQUETTA) STATUS(F) DESCR(PASQUETTA) 
CLDATE DATE(!GF_LIBERAZIONE) STATUS(F) DESCR(LIBERAZIONE) 
CLDATE DATE(!GF_LAVORO) STATUS(F) DESCR(FESTA DEI LAVORO) 
CLDATE DATE(!GF_REPUBBLICA) STATUS(F) DESCR(FESTA DEI REPUBBLICA) 
CLDATE DATE(!GF_FERRAGOSTO) STATUS(F) DESCR(FERRAGOSTO) 
CLDATE DATE(!GF_TUTTI_I_SANTI) STATUS(F) DESCR(TUTTI I SANTI) 
CLDATE DATE(!GF_IMMACOLATA) STATUS(F) DESCR(IMMACOLATA CONCEZIONE)
CLDATE DATE(!GF_NATALE) STATUS(F) DESCR(NATALE) 
CLDATE DATE(!GF_SANTA_STEFANO) STATUS(F) DESCR(SANTA STEFANO) 
Note:
  1. In some countries, rules relating to public holidays falling on weekends may vary regionally. In this case, the RULE keyword is not coded in the DATE member so that a regionally appropriate statement can be coded before referencing the DATE member. See the comments within the DATE member before using it. For example:
    VARDATE = RULE(NEAREST)
    INCLUDE EQQFILE(DATEUS)
  2. The DATExx members are provided to help ease the generation of calendars; if the rules do not meet your requirements, you can create your own versions.
  3. When VARDATE is run, message 033 is issued to show the value that is set. This also adds the day of the week at the end of the message to confirm that the date was set as you expected, as shown in the following example:
    EQQI033A Variable TO set to 1503082100 (Sunday)
    You can modify the contents of this confirmation aid by specifying an alternative format with OPTIONS VARDATE.