Document revision date: 30 March 2001

## OpenVMS Programming Concepts Manual

Previous | Contents | Index

## Chapter 27
System Time Operations

This chapter describes the types of system time operations performed by the operating system and contains the following sections:

Section 27.1 describes the system time format.

Section 27.2 describes time conversion and date/time manipulation.

Section 27.3 describes how to get the current date and time and set the current time.

Section 27.4 describes how to set and cancel timer requests and how to schedule and cancel wakeups.

Section 27.5 describes using run-time library (RTL) routines to collect timer statistics.

Section 27.6 describes using date/time formatting routines.

Section 27.7 describes the Coordinated Universal Time (UTC) system.

## 27.1 System Time Format

The operating system maintains the current date and time in 64-bit format. The time value is a binary number in 100-nanosecond (ns) units offset from the system base date and time, which is 00:00 o'clock, November 17, 1858 (the Smithsonian base date and time for the astronomic calendar). Time values must be passed to or returned from system services as the address of a quadword containing the time in 64-bit format. A time value can be expressed as either of the following:

- An absolute time that is a specific date or time of day, or both. Absolute times are always positive values (or 0).
- A delta time that is an offset from the current time to a time or date in the future. Delta times are always expressed as negative values.

If you specify 0 as the address of a time value, the operating system supplies the current date and time.

### 27.1.1 Absolute Time Format

The operating system uses the following format for absolute time. The full date and time require a character string of 23 characters. The punctuation is required.

`dd-MMM-yyyy hh:mm:ss.cc`

dd | Day of the month (2 characters)
MMM | Month (first 3 characters of the month in uppercase)
yyyy | Year (4 characters)
hh | Hours of the day in 24-hour format (2 characters)
mm | Minutes (2 characters)
ss.cc | Seconds and hundredths of a second (5 characters)

### 27.1.2 Delta Time Format

The operating system uses the following format for delta time. The full date and time require a character string of 16 characters. The punctuation is required.

`dddd hh:mm:ss.cc`

dddd | Day of the month (4 characters)
hh | Hour of the day (2 characters)
mm | Minutes (2 characters)
ss.cc | Seconds and hundredths of a second (5 characters)

A delta time is maintained as an integer value representing an amount of time in 100-ns units.

## 27.2 Time Conversion and Date/Time Manipulation

This section presents information about time conversion and date/time manipulation features, and the routines available to implement them.

### 27.2.1 Time Conversion Routines

Since the timer system services require you to specify the time in a 64-bit format, you can use time conversion run-time library and system service routines to work with time in a different format. Run-time library and system services do the following:

- Obtain the current date and time in an ASCII string or in system format
- Convert an ASCII string into the system time format
- Convert a system time value into an ASCII string
- Convert the time from system format to integer values

Table 27-1 shows time conversion run-time and system service routines.

Table 27-1 Time Conversion Routines and System Services
Routine | Function
--- | ---
Time Conversion Run-Time Library (LIB$) Routines
LIB$CONVERT_DATE_STRING | Converts an input date/time string to an operating system internal time.
LIB$CVT_FROM_INTERNAL_TIME | Converts an operating system standard internal binary time value to an external integer value. The value is converted according to a selected unit of time operation.
LIB$CVTF_FROM_INTERNAL_TIME | Converts an operating system standard internal binary time to an external F-floating point value. The value is converted according to a selected unit of time operation.
LIB$CVT_TO_INTERNAL_TIME | Converts an external integer time value to an operating system standard internal binary time value. The value is converted according to a selected unit of time operation.
LIB$CVTF_TO_INTERNAL_TIME | Converts an F-floating-point time value to an internal binary time value.
LIB$CVT_VECTIM | Converts a seven-word array (as returned by the SYS$NUMTIM system service) to an operating system standard format internal time.
LIB$FORMAT_DATE_TIME | Allows you to select at run time a specific output language and format for a date or time, or both.
LIB$SYS_ASCTIM | Provides a simplified interface between higher-level languages and the $ASCTIM system service.
Time Conversion System Service Routines
SYS$ASCTIM | Converts an absolute or delta time from 64-bit binary time format to an ASCII string.
SYS$ASCUTC | Converts an absolute time from 128-bit Coordinated Universal Time (UTC) format to an ASCII string.
SYS$BINTIM | Converts an ASCII string to an absolute or delta time value in a binary time format.
SYS$BINUTC | Converts an ASCII string to an absolute time value in the 128-bit UTC format.
SYS$FAO | Converts a binary value into an ASCII character string in decimal, hexadecimal, or octal notation and returns the character string in an output string.
SYS$GETUTC | Returns the current time in 128-bit UTC format.
SYS$NUMTIM | Converts an absolute or delta time from 64-bit system time format to binary integer date and time values.
SYS$NUMUTC | Converts an absolute 128-bit binary time into its numeric components. The numeric components are returned in local time.
SYS$TIMCON | Converts 128-bit UTC to 64-bit system format or 64-bit system format to 128-bit UTC based on the value of the convert flag.

You can use the SYS$GETTIM system service to get the current time in internal format, or you can use SYS$BINTIM to convert a formatted time to an internal time, as shown in Section 27.3.2. You can also use the LIB$DATE_TIME routine to obtain the time, LIB$CVT_FROM_INTERNAL_TIME to convert an internal time to an external time, and LIB$CVT_TO_INTERNAL to convert from an external time to an internal time.

#### 27.2.1.1 Calculating and Displaying Time with SYS$GETTIM and LIB$SUBX

Example 27-1 calculates differences between the current time and a time input in absolute format, and then displays the result as delta time. If the input time is later than the current time, the difference is a negative value (delta time) and can be displayed directly. If the input time is an earlier time, the difference is a positive value (absolute time) and must be converted to delta time before being displayed. To change an absolute time to a delta time, negate the time array by subtracting it from 0 (specified as an integer array) using the LIB$SUBX routine, which performs subtraction on signed two's complement integers of arbitrary length. For the absolute or delta time format, see Section 27.1.1 and Section 27.1.2.

Example 27-1 Calculating and Displaying the Time

       .
       .
       .
    ! Internal times
    ! Input time in absolute format, dd-mmm-yyyy hh:mm:ss.ss
    !
    INTEGER*4 CURRENT_TIME (2),
    2         PAST_TIME (2),
    2         TIME_DIFFERENCE (2),
    2         ZERO (2)
    DATA ZERO /0,0/
    ! Formatted times
    CHARACTER*23 PAST_TIME_F
    CHARACTER*16 TIME_DIFFERENCE_F
    ! Status
    INTEGER*4 STATUS
    ! Integer functions
    INTEGER*4 SYS$GETTIM,
    2         LIB$GET_INPUT,
    2         SYS$BINTIM,
    2         LIB$SUBX,
    2         SYS$ASCTIM
    ! Get current time
    STATUS = SYS$GETTIM (CURRENT_TIME)
    IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL (STATUS))
    ! Get past time and convert to internal format
    STATUS = LIB$GET_INPUT (PAST_TIME_F,
    2                       'Past time (in absolute format): ')
    IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL (STATUS))
    STATUS = SYS$BINTIM (PAST_TIME_F,
    2                    PAST_TIME)
    IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL (STATUS))
    ! Subtract past time from current time
    STATUS = LIB$SUBX (CURRENT_TIME,
    2                  PAST_TIME,
    2                  TIME_DIFFERENCE)
    IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL (STATUS))
    ! If resultant time is in absolute format (positive value means
    ! most significant bit is not set), convert it to delta time
    IF (.NOT. (BTEST (TIME_DIFFERENCE(2),31))) THEN
      STATUS = LIB$SUBX (ZERO,
    2                    TIME_DIFFERENCE,
    2                    TIME_DIFFERENCE)
    END IF
    ! Format time difference and display
    STATUS = SYS$ASCTIM (, TIME_DIFFERENCE_F,
    2                    TIME_DIFFERENCE,)
    IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL (STATUS))
    TYPE *, 'Time difference = ', TIME_DIFFERENCE_F
    END

If you are ignoring the time portion of date/time (that is, working just at the date level), the LIB$DAY routine might simplify your calculations. LIB$DAY returns to you the number of days from the base system date to a given date.

#### 27.2.1.2 Obtaining Absolute Time with SYS$ASCTIM and SYS$BINTIM

The Convert Binary Time to ASCII String (SYS$ASCTIM) system service is the converse of the Convert ASCII String to Binary Time (SYS$BINTIM) system service. You provide the service with the time in the ASCII format shown in Section 27.3.2. The service then converts the string to a time value in 64-bit format. You can use this returned value as input to a timer scheduling service.

When you specify the ASCII string buffer, you can omit any of the fields, and the service uses the current date or time value for the field. Thus, if you want a timer request to be date independent, you could format the input buffer for the SYS$BINTIM service as shown in the following example. The two hyphens that are normally embedded in the date field must be included, and at least one blank must precede the time field.

    #include <stdio.h>
    #include <descrip.h>

    /* Buffer to receive binary time */
    struct {
            unsigned int buff1, buff2;
    }binary_noon;

    main()  {

            unsigned int status;
            $DESCRIPTOR(ascii_noon,"-- 12:00:00.00");  /* noon (absolute time) */

    /* Convert time */
            status = SYS$BINTIM(&ascii_noon,        /* timbuf - ASCII time */
                     &binary_noon);                 /* timadr - binary time */

    }

When the SYS$BINTIM service completes, a 64-bit time value representing "noon today" is returned in the quadword at BINARY_NOON.

#### 27.2.1.3 Obtaining Delta Time with SYS$BINTIM

The SYS$BINTIM system service also converts ASCII strings to delta time values to be used as input to timer services. The buffer for delta time ASCII strings has the following format:

`dddd hh:mm:ss.cc`

The first field, indicating the number of days, must be specified as 0 if you are specifying a delta time for the current day.

The following example shows how to use the SYS$BINTIM service to obtain a delta time in system format:

    #include <stdio.h>
    #include <descrip.h>

    /* Buffer to receive binary time */
    struct {
            unsigned int buff1, buff2;
    }btenmin;

    main()  {

            unsigned int status;
            $DESCRIPTOR(atenmin,"0 00:10:00.00");  /* 10-min delta */

    /* Convert time from ASCII to binary */
            status = SYS$BINTIM(&atenmin,   /* timbuf - time in ASCII */
                    &btenmin);              /* timadr - binary time */

    }

If you are programming in VAX MACRO, you can also specify approximate delta time values when you assemble a program, using two MACRO .LONG directives to represent a time value in 100-ns units. The arithmetic is based on the following formula:

    1 second = 10 million * 100 ns

For example, the following statement defines a delta time value of 5 seconds:

    FIVESEC:  .LONG -10*1000*1000*5,-1 ; Five seconds

The value 10 million is expressed as 10*1000*1000 for readability. Note that the delta time value is negative.

If you use this notation, however, you are limited to the maximum number of 100-ns units that can be expressed in a longword. In time values this is slightly more than 7 minutes.

#### 27.2.1.4 Obtaining Numeric and ASCII Time with SYS$NUMTIM

The Convert Binary Time to Numeric Time (SYS$NUMTIM) system service converts a time in the system format into binary integer values. The service returns each of the components of the time (year, month, day, hour, and so on) into a separate word of a 7-word buffer. The SYS$NUMTIM system service and the format of the information returned are described in the OpenVMS System Services Reference Manual.

You use the SYS$ASCTIM system service to format the time in ASCII for inclusion in an output string. The SYS$ASCTIM service accepts as an argument the address of a quadword that contains the time in system format and returns the date and time in ASCII format.

If you want to include the date and time in a character string that contains additional data, you can format the output string with the Formatted ASCII Output (SYS$FAO) system service. The SYS$FAO system service converts binary values to ASCII representations, and substitutes the results in character strings according to directives supplied in an input control string. Among these directives are !%T and !%D, which convert a quadword time value to an ASCII string and substitute the result in an output string. For examples of how to do this, see the discussion of $FAO in the OpenVMS System Services Reference Manual.

### 27.2.2 Date/Time Manipulation Routines

The run-time LIB$ facility provides several date/time manipulation routines. These routines let you add, subtract, and multiply dates and times. Use the LIB$ADDX and LIB$SUBX routines to add and subtract times, since the times are defined in integer arrays. Use LIB$ADD_TIMES and LIB$SUB_TIMES to add and subtract two quadword times. When manipulating delta times, remember that they are stored as negative numbers. For example, to add a delta time to an absolute time, you must subtract the delta time from the absolute time. Use LIB$MULT_DELTA_TIME and LIB$MULTF_DELTA_TIME to multiply delta times by scalar and floating scalar.

Table 27-2 lists all the LIB$ routines that perform date/time manipulation.

Table 27-2 Date/Time Manipulation Routines
Routine | Function
--- | ---
LIB$ADD_TIMES | Adds two quadword times
LIB$FORMAT_DATE_TIME | Formats a date and/or time for output
LIB$FREE_DATE_TIME_CONTEXT | Frees the date/time context
LIB$GET_MAXIMUM_DATE_LENGTH | Returns the maximum possible length of an output date/time string
LIB$GET_USERS_LANGUAGE | Returns the user's selected language
LIB$INIT_DATE_TIME_CONTEXT | Initializes the date/time context with a user-specified format
LIB$MULT_DELTA_TIME | Multiplies a delta time value by an integer scalar value
LIB$MULTF_DELTA_TIME | Multiplies a delta time value by an F-floating point scalar value
LIB$SUB_TIMES | Subtracts two quadword times

## 27.3 Timer Routines Used to Obtain and Set Current Time

This section presents information about obtaining the current date and time, and setting current time. The run-time library (LIB$) facility provides date/time utility routines for languages that do not have built-in time and date functions. These routines return information about the current date and time or a date/time specified by the user. You can obtain the current time by using the LIB$DATE_TIME routine or by implementing the SYS$GETTIM system service. To set the current time, use the SYS$SETTIME system service.

Table 27-3 describes the date/time routines.

Table 27-3 Timer RTLs and System Services
Routine | Function
--- | ---
Timer Run-Time Library (LIB$) Routines
LIB$DATE_TIME | Returns, using a string descriptor, the operating system date and time in the semantics of a string that the user provides.
LIB$DAY | Returns the number of days since the system zero date of November 17, 1858. This routine takes one required argument and two optional arguments: The address of a longword to contain the number of days since the system zero date (required) A quadword passed by reference containing a time in system time format to be used instead of the current system time (optional) A longword integer to contain the number of 10-millisecond units since midnight (optional)
LIB$DAY_OF_WEEK | Returns the numeric day of the week for an input time value. If the input time value is 0, the current day of the week is returned. The days are numbered 1 through 7: Monday is day 1 and Sunday is day 7.
System Service Routine
SYS$SETIME | Changes the value of or recalibrates the system time.

### 27.3.1 Obtaining Current Time and Date with LIB$DATE_TIME

The LIB$DATE_TIME routine returns a character string containing the current date and time in absolute time format. The full string requires a declaration of 23 characters. If you specify a shorter string, the value is truncated. A declaration of 16 characters obtains only the date. The following example displays the current date and time:

    ! Formatted date and time
    CHARACTER*23 DATETIME
    ! Status and library procedures
    INTEGER*4 STATUS,
    2         LIB$DATE_TIME
    EXTERNAL  LIB$DATE_TIME
    STATUS = LIB$DATE_TIME (DATETIME)
    IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL (STATUS))
    TYPE *, DATETIME

### 27.3.2 Obtaining Current Time and Date with SYS$GETTIM

You can obtain the current date and time in internal format with the SYS$GETTIM system service. You can convert from internal to character format with the SYS$ASCTIM system service or a directive to the SYS$FAO system service and convert back to internal format with the SYS$BINTIM system service. The Get Time (SYS$GETTIM) system service places the time into a quadword buffer. For example:

    /* Buffer to receive the binary time */
    struct {
            unsigned int buff1, buff2;
    }time;

       .
       .
       .
    main() {

            unsigned status;

This call to SYS$GETTIM returns the current date and time in system format in the quadword buffer TIME.

The Convert Binary Time to ASCII String (SYS$ASCTIM) system service converts a time in system format to an ASCII string and returns the string in a 23-byte buffer. You call the SYS$ASCTIM system service as follows:

    #include <stdio.h>
    #include <descrip.h>

    struct {
            unsigned int buff1, buff2;
    }time_value;

    main() {

            unsigned int status;
            char timestr[23];
            $DESCRIPTOR(atimenow, timestr);

    /* Get binary time */
            status = SYS$GETTIM(&time_value);
            if ((status & 1) != 1)
                    LIB$SIGNAL( status );

    /* Convert binary time to  ASCII */
            status = SYS$ASCTIM(0,            /* timlen - Length of ASCII string */
                                &atimenow,    /* timbuf - ASCII time buffer */
                                &time_value,  /* timadr - Binary time */
                                0);           /* cvtflags - Conversion indicator */
            if ((status & 1) != 1)
                    LIB$SIGNAL( status );

    }

Because the address of a 64-bit time value is not supplied, the default value, 0, is used.

The string the service returns has the following format:

`dd-MMM-yyyy hh:mm:ss.cc`

dd | Day of the month
MMM | Month (a 3-character alphabetic abbreviation)
yyyy | Year
hh:mm:ss.cc | Time in hours, minutes, seconds, and hundredths of a second

Previous | Next | Contents | Index

| privacy and legal statement |
5841PRO_072.HTML