$HOROLOG (ObjectScript)
Synopsis
$HOROLOG
$H
Description
$HOROLOG contains the date and time for the current process. It can contain the following values:
-
The current local date and time.
-
The current local date and time, adjusted for a different time zone offset.
-
A user-specified non-incrementing date. Time continues to be the current local time.
$HOROLOG contains a character string that consists of two integer values, separated by a comma. These two integers represent the current local date and time in InterSystems IRIS storage format. These integers are counters, not user-readable dates and times. $HOROLOG returns the current date and time in the following format:
ddddd,sssss
The first integer, ddddd, is the current date expressed as a count of the number of days since December 31, 1840, where day 1 is January 1, 1841. Because InterSystems IRIS represents dates using a counter from an arbitrary starting point, InterSystems IRIS is unaffected by the Year 2000 boundary. The maximum value for this date integer is 2980013, which corresponds to December 31, 9999.
The second integer, sssss, is the current time, expressed as a count of the number of seconds since midnight of the current day. The system increments the time field from 0 to 86399 seconds. When it reaches 86399 at midnight, the system resets the time field to 0 and increments the date field by 1. $HOROLOG truncates fractional seconds; it represents time in whole seconds only.
You can obtain the same current date and time information by invoking the Horolog()Opens in a new tab method, as follows:
WRITE $SYSTEM.SYS.Horolog()
Refer to %SYSTEM.SYSOpens in a new tab in the InterSystems Class Reference for further details.
Separating Date and Time
To get just the date portion or just the time portion of $HOROLOG, you can use the $PIECE function, specifying the comma as the delimiter character:
SET dateint=$PIECE($HOROLOG,",",1)
SET timeint=$PIECE($HOROLOG,",",2)
WRITE !,"Date and time: ",$HOROLOG
WRITE !,"Date only: ",dateint
WRITE !,"Time only: ",timeint
To get just the date portion of a $HOROLOG value, you can also use the following programming trick:
SET dateint=+$HOROLOG
WRITE !,"Date and time: ",$HOROLOG
WRITE !,"Date only: ",dateint
The plus sign (+) causes InterSystems IRIS to parse the $HOROLOG string as a number. When InterSystems IRIS encounters a nonnumeric character (the comma), it truncates the rest of the string and returns the numeric portion. This is the date integer portion of the string.
Date and Time Functions Compared
The various ways to return the current date and time are compared, as follows:
-
$HOROLOG contains the local, variant-adjusted date and time in InterSystems IRIS storage format. The local time zone is determined from the current value of the $ZTIMEZONE special variable, and then adjusted for local time variants, such as Daylight Saving Time. It returns whole seconds only; fractions of a second are truncated.
-
$NOW returns the local date and time for the current process. $NOW returns the date and time in InterSystems IRIS storage format. It includes fractional seconds; the number of fractional digits is the maximum precision supported by the current operating system.
-
$NOW() determines the local time zone from the value of the $ZTIMEZONE special variable. The local time is not adjusted for local time variants, such as Daylight Saving Time. It therefore may not correspond to local clock time.
-
$NOW(tzmins) returns the time and date that correspond to the specified tzmins time zone parameter. The value of $ZTIMEZONE is ignored.
-
-
$ZTIMESTAMP contains the UTC (Coordinated Universal Time) date and time, with fractional seconds, in InterSystems IRIS storage format. Fractional seconds are expressed in three digits of precision (on Windows systems), or six digits of precision (on UNIX® systems).
Date and Time Conversions
You can use the $ZDATE function to convert the date portion of $HOROLOG into external, user-readable form. You can use the $ZTIME function to convert the time portion of $HOROLOG into external user-readable form. You can use the $ZDATETIME function to convert both the date and time. When using $HOROLOG, setting the precision for time values in these functions always returns zeros as fractional seconds.
You can use the $ZDATEH function to convert a user-readable date into the date portion of $HOROLOG. You can use the $ZTIMEH function to convert a user-readable time into the time portion of $HOROLOG. You can use the $ZDATETIMEH function to convert both the date and time to a $HOROLOG value.
Setting the Date and Time
$HOROLOG can be set to a user-specified date for the current process using the FixedDate()Opens in a new tab method of the %SYSTEM.ProcessOpens in a new tab class. $HOROLOG cannot be modified using the SET command. Attempting to do so results in a <SYNTAX> error.
DO ##class(%SYSTEM.Process).FixedDate(12345) // set $HOROLOG date
WRITE !,$ZDATETIME($HOROLOG,1,1,9)," $HOROLOG changed date"
WRITE !,$ZDATETIME($NOW(),1,1,9)," $NOW() no date change"
WRITE !,$ZDATETIME($ZDATETIMEH($ZTIMESTAMP,-3),1,1,9)," $ZTS UTC-to-local",
" no date change"
DO ##class(%SYSTEM.Process).FixedDate(0) // restore $HOROLOG
WRITE !,$ZDATETIME($HOROLOG,1,1,9)," $HOROLOG current date"
Note that FixedDate() changes the $HOROLOG value, but not the $NOW or $ZTIMESTAMP value.
Time Zone
By default, $HOROLOG contains the date and time for the local time zone. This time zone default is supplied by the operating system, which InterSystems IRIS uses to set the $ZTIMEZONE default.
Changing $ZTIMEZONE affects the value of $HOROLOG for the current process. It changes the time portion of $HOROLOG, and this change of time can also change the date portion of $HOROLOG. $ZTIMEZONE is a fixed offset of time zones from the Greenwich meridian; it does not adjust for local seasonal time variants, such as Daylight Saving Time.
Daylight Saving Time
$HOROLOG adjusts for seasonal time variants based on the algorithm supplied by the underlying operating system. After applying the $ZTIMEZONE value, InterSystems IRIS uses the operating system local time to adjust $HOROLOG (if needed) for seasonal time variants, such as Daylight Saving Time.
You can determine if Daylight Saving Time is in effect for the current date, or for a specified date and time using the IsDST()Opens in a new tab method. The following example returns the Daylight Saving Time (DST) status for the current date and time. Because this status could change while the program is running, this example checks it twice:
CheckDST
SET x=$SYSTEM.Util.IsDST()
SET local=$ZDATETIME($HOROLOG)
SET x2=$SYSTEM.Util.IsDST()
GOTO:x'=x2 CheckDST
IF x=1 {WRITE local," DST in effect"}
ELSEIF x=0 {WRITE local," DST not in effect"}
ELSE {WRITE local," DST setting cannot be determined"}
The application of seasonal time variants may differ based on (at least) three considerations:
-
Operating system: Within a time zone, $HOROLOG for a given date may differ on different computers. This is because different operating systems use different algorithms to apply time variants. Because policies governing the beginning and end dates for Daylight Saving Time (and other time variants) have changed, older operating systems may not reflect current practice, and/or calculations using older $HOROLOG values may be adjusted using the current beginning and end dates, rather than the ones in force at that time.
-
Government policies have changed over time: There have been numerous changes to seasonal time variants since their first adoption in 1916 (much of Europe) and 1918 (United States). Daylight Saving Time has been adopted, rejected, and re-adopted by governmental policies in many places. The seasonal start and end dates for Daylight Saving Time have also changed numerous times. In the United States, recent changes of national policy have occurred in 1966, 1974–75, 1987, and 2007. Adoption of, or exemption from, national policies have also occurred due to local legislative actions. For example, the state of Arizona does not observe Daylight Saving Time.
-
Geography: Daylight Saving Time is summer time; the local clock shifts forwards (“Spring ahead”) at the start of DST and shifts backwards (“Fall back”) at the end of DST. Thus the calendar start and end dates for Daylight Saving Time within the same time zone are commonly reversed in the northern hemisphere and the southern hemisphere. Equatorial nations and most of Asia and Africa do not observe Daylight Saving Time.
Local Time Variant Thresholds
$HOROLOG calculates the number of seconds from midnight by consulting the system clock. Therefore, if the system clock is automatically reset when crossing a local time variant threshold, such as the beginning or end of Daylight Saving Time, the time value of $HOROLOG also shifts abruptly ahead or back by the appropriate number of seconds. For this reason, comparisons of two $HOROLOG time values may yield unanticipated results if the period between the two values includes a local time variant threshold.
$NOW does not adjust for local time variants. Its use may be preferable when comparing date and time values if the period between the two values includes a local time variant threshold.
Dates Before 1840
$HOROLOG cannot be directly used to represent dates outside of the range of years 1840 through 9999. However, you can represent historic dates far beyond this range using the InterSystems SQL Julian date feature. Julian dates can represent a date as an unsigned integer, counting from 4711 BC (BCE). Julian dates do not have a time-of-day component.
You can convert an InterSystems IRIS $HOROLOG date to an InterSystems IRIS Julian date using the TO_CHAR SQL function, or the TOCHAR()Opens in a new tab method of the %SYSTEM.SQLOpens in a new tab class. You can convert an InterSystems IRIS Julian date to an InterSystems IRIS $HOROLOG date using the TO_DATE SQL function, or the TODATE()Opens in a new tab method of the %SYSTEM.SQLOpens in a new tab class.
The following example takes the current $HOROLOG date and converts it to a Julian date. The + before $HOROLOG forces InterSystems IRIS to treat it as a number, and thus truncate at the comma, eliminating the time integer:
WRITE !,"Horolog date = ",+$H
SET x=$SYSTEM.SQL.TOCHAR(+$HOROLOG,"J")
WRITE !,"Julian date = ",x
The following example takes a Julian date and converts it to an InterSystems IRIS $HOROLOG date:
SET x=$SYSTEM.SQL.TODATE(2455030,"J")
WRITE !,"$HOROLOG date = ",x," = ", $ZDATE(x,1)
Note that Julian date values smaller than 1721100 cannot be converted; an <ILLEGAL VALUE> error is generated.
For further information on Julian dates, refer to TO_DATE and TO_CHAR.
Examples
The following example displays the current contents of $HOROLOG.
WRITE $HOROLOG
This returns a value formatted like this: 64701,49170
The following example uses $ZDATE to convert the date field in $HOROLOG to a date format.
WRITE $ZDATE($PIECE($HOROLOG,",",1))
returns a value formatted like this: 02/22/2018
The following example converts the time portion of $HOROLOG to a time in the form of hours:minutes:seconds on a 12-hour (a.m. or p.m.) clock.
CLOCKTIME
NEW
SET Time=$PIECE($HOROLOG,",",2)
SET Sec=Time#60
SET Totmin=Time\60
SET Min=Totmin#60
SET Milhour=Totmin\60
IF Milhour=12 { SET Hour=12,Meridian=" pm" }
ELSEIF Milhour>12 { SET Hour=Milhour-12,Meridian=" pm" }
ELSE { SET Hour=Milhour,Meridian=" am" }
WRITE !,Hour,":",Min,":",Sec,Meridian
QUIT
See Also
-
$NOW function
-
$ZDATE function
-
$ZDATEH function
-
$ZDATETIME function
-
$ZDATETIMEH function
-
$ZTIME function
-
$ZTIMEH function
-
$ZTIMESTAMP special variable
-
$ZTIMEZONE special variable