ibm REXX home page
Handling DATES with REXX

Table of contents

  • Basic rules
  • Calculation and conversion
  • Formatting for output
  • Some useful functions
  • Retrieving File Dates
  • Basic rules

    Initially, here are the basic rules that prevent problems related to dates with respect to the year 2000, frequently called the Y2K problem.

    Rule I:

    Always use the 'Base' date format for any date calculations and internal date data.

    Rule II:

    Always use the 'Standard' date format (ISO standard) to store a human readable date.

    Rule III:

    Always use 'Base' date, or alternatively the 'Standard' date format for sorting.
    ('Base' date format provides best performance)

    Rule IV:

    Always convert from either 'Base' or 'Standard' date format to any individual (external) format used for presentation to the human eye including any national language defined NLS formats.

    Rule V:

    Convert your data from any of the 'deficient' old formatted date data to either 'Base' or 'Standard' date format as soon as possible!

    Remark: Note that the date conversion function is not available in OS/2 Warp and REXX/6000. Please be also aware that the functions retrieving file dates are not available in VM/CMS and MVS/TSO. If you run OS/2 you are advised to switch to Object REXX using the SWITCHRX command. In any case, in particular when working on VM/CMS or MVS/TSO you should make sure to have the latest release of REXX installed.

    Calculation and conversion

    Here are some examples how to use REXX built-in functions to solve usual date calculation and conversion problems:

    Yesterday or tomorrow:
    /* get today's date in 'Base' date format, e.g. '729584' */
    today = Date('Base') 
    /* calculate next day; returns '729585' */ tomorrow = today + 1
    /* calculate previous day; returns '729583' */ yesterday = today - 1
    Date conversion:

    To any format supported by the Date built-in function:

                       /* returns '19980715'                 */
    ISOdate = Date('Standard', today, 'Base')
    /* returns '07/15/98' */ USdate = Date('Usa',today, 'Base')
    /* returns '15 Jul 1998' */ Ndate = Date('Normal', today, 'Base')
    Day of the year:

    The day within the year of today, the July 15, 1998 (current date):

    day = Date('Days') /* returns 196                        */
    
    Weekday of a particular date:
    /* returns 'Wednesday'                                   */
    weekday = Date('Weekday', '07/15/98', 'Usa')
    /* returns 2, 0 = Monday, 6 = Sunday */ dayOfWeek = Date('Base', '07/15/98', 'Usa')//7
    Date difference:
                       /* returns 20091 days                 */
    days = today - Date('Base', '19430715', 'Standard')
    
    Month of day in year:

    Calculating the name of the month a particular date is in.

                       /* returns 'September'                */
    month = Date('Month', 250 ,'Days')
    

    Formatting for output or input

    By means of the translate function, a date format (assuming 'Standard' date format) can be easily transformed (by reordering the digits and inserting or removing separation characters) into any format desired with a single REXX statement:
    /* ISO Standard date format without separator characters */
    myISOdate = '19430715'
                       /* returns '15-07-1943'               */
    date1 = Translate('78-56-1234', myISOdate, '12345678')
                       /* returns '07/15/1943'               */
    date2 = Translate('56/78/1234', myISOdate, '12345678')
                       /* returns '15/07/1943'               */
    date3 = Translate('78/56/1234', myISOdate, '12345678')
    
    Similarly, the converse transformation allows to easily get an ISO date format from any date format with separators, by example:
    date1 = '15-07-1943'
                       /* returns '19430715'                 */
    myISOdate = Translate('78904512', date1, '1234567890')
    
    date2 = '07/15/1943'
                       /* returns '19430715'                 */
    myISOdate = Translate('78901245', date2, '1234567890')
    
    /* ISO Standard date format with separator characters    */
    anISOdate = '1943-07-15'
    /* returns ISO Standard date w/o separators '19430715'   */
    myISOdate =  Translate('12346790', anISOdate, '1234567890')
    
    Another quite useful feature of REXX is the windowed handling of the 'deficient' short date formats currently causing so much trouble because of the Y2K. In this case, REXX by default uses the hundreds within the window
    today + 49 and today - 50 years.
    
    Therefore, the 'Usa' date '07/15/43' is interpreted as 'Standard' date '20430715' because the year 1943 would be outside the 100 year wide window of today, July 17, 1998! In this way, all dates within 50 years around the current date are converted correctly without additional programming effort.

    Some useful functions

    Date validation

    The validity of a date in a defined format, e.g. ISO date, is checked easily as follows:

    /* function checking the validity of an ISO date         */
    valiDate: procedure
    parse arg ISOdate
    
    /* catch syntax error produced by wrong date value       */
    signal on syntax
    dummy = Date(, ISOdate, 'Standard')
    return 0           /* is valid date                      */
    syntax:
    return 1           /* is invalid date                    */
    
    Test for Leap Year

    The same technique can be used to implement a functions that checks if the input date falls in a leap year:

    /* function checking for a leap year of an ISO date      */
    isLeap: procedure
    parse arg ISOdate
    
    /* catch syntax error produced by wrong date value       */
    signal on syntax
    dummy = Date(, substr(ISOdate,1,4)'0229', 'Standard')
    return 1           /* is valid date, --> leap year       */
    syntax:
    return 0           /* is invalid date, --> no leap year  */
    
    Daylight Saving Dates

    Another useful example shows the calculation of the dates for the Daylight Savings Time in the United States:

    /* US daylight saving time dates for a year              */
    dsDates: procedure
    parse arg year
    
    if arg() = 0 then do
                       /* Help text                          */
       say 'Calculate the beginning and ending of Daylight'
       say 'Savings Time in the US'
       say '  (First Sunday in April and last Sunday in October)'
       say 'Usage: dsDates '
       return
    end
    
    /* Calculate Daylight start in base format               */
    DaylightStart = Date('Base', year'0401','Standard')
    DayOfWeek =  DaylightStart//7
    
    /* If April 1st isn't a Sunday,                          */
    if DayOfWeek < 6 then
                       /* take the next one                  */
       DaylightStart = DaylightStart + 6 - DayOfWeek
    
    /* Calculate Daylight end in base format                 */
    DaylightEnd = Date('Base', year'1031', 'Standard')
    DaylightEnd = DaylightEnd - (DaylightEnd + 1)//7
                       /* get today's date                   */
    Today = Date('Base')
    
    /* format the output dates                               */
    SO = Translate('345.61,67890', Date(, DaylightStart, 'Base'),'1234567890')
    EO = Translate('456.712,7890A', Date(, DaylightEnd, 'Base'),'1234567890A')
    
    /* write the output                                      */
    say 'US Daylight Savings Time in' year
    say '  starts on:' SO ' ('DaylightStart - Today 'days from now)'
    say '  ends on:' EO '  ('DaylightEnd - Today 'days from now)'
    return
    

    Retrieving file dates

    To retrieve a date associated with a file, two alternatives are available, the Stream built-in function and the REXX Utility function SysFileTree. How these are properly used is described in the following examples.

    Stream built-in function

    This example shows how to get the date a file was created or last modified using the Stream built-in function with the command "QUERY TIMESTAMP":

    /* get the date the file "profile.txt" was last modified */
    filedate = stream("profile.txt", 'c', 'QUERY TIMESTAMP')
    /* returns the date in ISO format, e.g. 1995-11-12       */
    say filedate
    

    Note: The old command "QUERY DATETIME' providing only a two digit year component is still supported but should not be used any longer.

    The SysFileTree utility function

    This utility function allows to retrieve the file information using option "L" as follows:

    /* get the date the file "profile.txt" was last modified */
    rc = SysFileTree("profile.txt", myStem., "L")
    /* says the date in ISO format, the time, etc., e.g.     */
    /*      "1995-11-12 12:24:55   45 A---- d:\profile.txt"  */
    say myStem.1
    

    Note: The old option 'T' providing only a two digit year component is still supported but should not be used any longer.

    Top of this page

    [ REXX | Home | Order | Search | Contact IBM | Terms of use ]

    This page used to found from http://www2.hursley.ibm.com/rexx.