Validates a date and converts it from internal format to the specified display format.
Description
The $ZDATE function converts a specified date in internal storage format ($HOROLOG format) to one of several alternate date display formats. The value returned by $ZDATE depends on the arguments you use.
Simple $ZDATE format
$ZDATE(hdate), the most basic form of $ZDATE, returns the date in a display format that corresponds to the specified hdate. hdate is an integer count of the number of days elapsed since December 31, 1840. It can range from 0 to 2980013 (12/31/1840 to 12/31/9999).
By default, $ZDATE(hdate) represents years between 1900 and 1999 with two digits. It represents years that fall before 1900 or after 1999 with four digits. For example:
WRITE $ZDATE(21400),! ; returns 08/04/1899
WRITE $ZDATE(50000),! ; returns 11/23/77
WRITE $ZDATE(60000),! ; returns 04/10/2005
WRITE $ZDATE(0),! ; returns 12/31/1840
When you supply a $HOROLOG date to $ZDATE, only the date portion is used. In $HOROLOG format, date and time are presented as two integers separated by a comma. Upon encountering the comma (a non-numeric character) $ZDATE ignores the rest of the string. In the following example, $ZDATE returns 04/10/2005 and the current date using $HOROLOG format values:
WRITE !,$ZDATE("60000,12345")
WRITE !,$ZDATE($HOROLOG)
Customizable Date Default
Upon InterSystems IRIS startup, the default date format is initialized to dformat=1, which is the American date format with a slash date separator (MM/DD/[YY]YY). To set this and other default formats to the values for your current locale, set the following global variable: SET ^SYS("NLS","Config","LocaleFormat")=1. This sets all format defaults for all processes to your current locale values. These defaults persist until this global is changed.
Note:
This section describes the user locale definitions applied when localeopt is undefined or set to 0. When localeopt=1, $ZDATE uses a predefined ODBC locale.
You can use NLS (National Language Support) to override format defaults for the current process. You can either change the all format defaults to the values for a specified locale, or change individual format values.
-
To set all of the format defaults (including the date format default) to the properties of a specified locale, invoke the following method call: SET fmt=##class(%SYS.NLS.Format).%New("lname"), where lname is the NLS name of the desired locale. (For example, deuw=German, espw=Spanish, fraw=French, ptbw=Brazilian Portuguese, rusw=Russian, jpnw=Japanese. A complete list of locales is found in the Management Portal: System Administration, Configuration, National Language Settings, Locale Definitions. To set these defaults to the properties of the current locale, specify a lname of "current", or the empty string ("").
-
To set the default date format to a specified dformat format, invoke the SetFormatItem()Opens in a new tab method: SET rtn=##class(%SYS.NLS.Format).SetFormatItem("DateFormat",n), where n is the number of the dformat value you wish to make the default.
The following example demonstrates setting all format defaults to the Russian locale, returning a date from $ZDATE in the default format (Russian), then resetting the format defaults to the current locale defaults. Note that the Russian locale uses a period, rather than a slash as the date part separator:
WRITE !,$ZDATE($HOROLOG)
SET fmt=##class(%SYS.NLS.Format).%New("rusw")
WRITE !,$ZDATE($HOROLOG)
SET fmt=##class(%SYS.NLS.Format).%New("current")
WRITE !,$ZDATE($HOROLOG)
The following example demonstrates setting individual format defaults. The first $ZDATE returns a date in the default format. The first SetFormatItem()Opens in a new tab method changes the default to dformat=4, or the European date format (DD/MM/[YY]YY), as is shown by the second $ZDATE. The second SetFormatItem() method changes the default for the date separator character (which affects the dformat -1, 1, 4, and 15). In this example, the date separator character is set to a dot (“.”), as is shown by the third $ZDATE. Finally, this program restores the original date format values:
InitialVals
SET fmt=##class(%SYS.NLS.Format).GetFormatItem("DateFormat")
SET sep=##class(%SYS.NLS.Format).GetFormatItem("DateSeparator")
WRITE !,$ZDATE($HOROLOG)
ChangeVals
SET x=##class(%SYS.NLS.Format).SetFormatItem("DateFormat",4)
WRITE !,$ZDATE($HOROLOG)
SET y=##class(%SYS.NLS.Format).SetFormatItem("DateSeparator",".")
WRITE !,$ZDATE($HOROLOG)
RestoreVals
SET x=##class(%SYS.NLS.Format).SetFormatItem("DateFormat",fmt)
SET y=##class(%SYS.NLS.Format).SetFormatItem("DateSeparator",sep)
WRITE !,$ZDATE($HOROLOG)
For further details on default date formats for supported locales, refer to Dates in Using ObjectScript.
Arguments
hdate
The internal date format value representing the number of days elapsed since December 31, 1840. By default, it must be an integer in the range 0 through 2980013. You can specify hdate as a numeric, a string literal, or an expression. InterSystems IRIS converts hdate to canonical form. It truncates a numeric string (such as a $HOROLOG value) at its first non-numeric character. It evaluates a non-numeric string as the integer 0. A floating-point number that does not resolve to an integer generates an <ILLEGAL VALUE> error.
By default, the earliest valid hdate is 0 (December 31, 1840). Dates are limited to positive integers by default because the DateMinimum property defaults to 0. You can specify earlier dates as negative integers, provided the DateMinimum property of the current locale is set to a greater or equal negative integer. The lowest valid DateMinimum value is -672045, which corresponds to January 1, 0001. InterSystems IRIS uses the proleptic Gregorian calendar, which projects the Gregorian calendar back to “Year 1”, in conformance with the ISO 8601 standard. This is, in part, because the Gregorian calendar was adopted at different times in different countries. For example, much of continental Europe adopted it in 1582; Great Britain and the United States adopted it in 1752. Thus InterSystems IRIS dates prior to your local adoption of the Gregorian calendar may not correspond to historical dates that were recorded based on the local calendar then in effect. For further details on dates prior to 1840, refer to the mindate argument.
Invalid and out-of-range hdate values and resulting errors are described in the erropt argument.
monthlist
An expression that resolves to a string of month names or month name abbreviations, separated by a delimiter character. The names in monthlist replace the default month abbreviation values from the MonthAbbr property or the month name values from the MonthName property of the current locale.
monthlist is valid only if dformat is 2, 5, 6, 7, 9, 18, or 20. If dformat is any other value $ZDATE ignores monthlist.
The monthlist string has the following format:
-
The first character of the string is a delimiter character (usually a space). The same delimiter must appear before the first month name and between each month name in monthlist. You can specify any single-character delimiter; this delimiter appears between the month, day, and year portions of the returned date value, which is why a space is usually the preferred character.
-
The month names string should contain twelve delimited values, corresponding to January through December. It is possible to specify more or less than twelve month names, but if there is no month name corresponding to the month in hdate an <ILLEGAL VALUE> error is generated.
If you omit monthlist or specify a monthlist value of -1, $ZDATE uses the list of month names defined in the MonthAbbr or MonthName property of the current locale, unless one of the following is true: If localeopt=1, the monthlist default is the ODBC month list (in English). If localeopt is unspecified and dformat is 18 or 20 (Islamic date formats) the monthlist default is the Islamic month list (Arabic names expressed using Latin letters), ignoring the MonthAbbr or MonthName property value.
To determine the default month names and month abbreviations for your locale, invoke the GetFormatItem()Opens in a new tab NLS class method:
WRITE ##class(%SYS.NLS.Format).GetFormatItem("MonthName"),!
WRITE ##class(%SYS.NLS.Format).GetFormatItem("MonthAbbr"),!
The following example lists the month names the default locale, changes the locale for this process to the Russian locale, then lists the Russian month names and displays the current date with a Russian month name. It then reverts the locale defaults to current locale and again displays the current date, this time with the default month name.
WRITE ##class(%SYS.NLS.Format).GetFormatItem("MonthName"),!
SET fmt=##class(%SYS.NLS.Format).%New("rusw")
WRITE fmt.MonthName,!
WRITE $ZDATE($HOROLOG,9),!
SET fmt=##class(%SYS.NLS.Format).%New()
WRITE $ZDATE($HOROLOG,9)
yearopt
With dformat values 1, 2, 4, 7, or 15, an integer code that specifies the temporal window in which to display the year as a two-digit value. For all other dformat values, the yearopt is ignored. Valid yearopt values are:
Value |
Meaning |
-1 |
Get effective yearopt value from YearOption property of current locale which defaults to a value of 0. This is the default behavior if you do not specify yearopt. |
0 |
Represent 20th century dates (1900 through 1999) with two-digit years and all other dates with four-digit years, unless a process-specific sliding window (established via the %DATE utility) is in effect. If such a window is in effect, represent only those dates falling within the sliding window by two-digit years, and all other dates with four-digit years. |
1 |
Represent 20th century dates with two-digit years and all other dates with four-digit years. |
2 |
Represent all dates with two-digit years. |
3 |
Represent with two-digit years those dates falling within the sliding temporal window defined by startwin and (optionally) endwin. Represent all other dates with four-digit years. When yearopt =3, startwin and endwin are absolute dates in $HOROLOG format. |
4 |
Represent all dates with four-digit years. ODBC year option. |
5 |
Represent with two-digit years all dates falling within the sliding temporal window defined by startwin and (optionally) endwin. Represent all other dates with four-digit years. When yearopt=5, startwin and endwin are relative years. |
6 |
Represent all dates in the current century with two-digit years and all other dates with four-digit years. |
To determine the default year option for your locale, invoke the GetFormatItem()Opens in a new tab NLS class method:
WRITE ##class(%SYS.NLS.Format).GetFormatItem("YearOption")
If you omit yearopt or specify a yearopt value of -1, $ZDATE uses the YearOption property of the current locale, unless one of the following is true: If localeopt=1, the yearopt default is the ODBC year option. If localeopt=0 or is unspecified and dformat is 18, 19, 20, or 21 (Islamic date formats) the yearopt default is the ODBC year option (4-digit years); the YearOption property value is ignored for Islamic dates.
startwin
A numeric value that specifies the start of the sliding window during which dates must be represented with two-digit years. See argument section. You must supply startwin when yearopt is 3 or 5. startwin is not valid with any other yearopt values.
When yearopt = 3, startwin is an absolute date in $HOROLOG date format that indicates the start date of the sliding window.
When yearopt = 5, startwin is a numeric value that indicates the start year of the sliding window expressed as the number of years before the current year. The sliding window always begins on January 1st of the year specified in startwin.
endwin
A numeric value that specifies the end of the sliding window during which dates are represented with two-digit years. You may optionally supply endwin when yearopt is 3 or 5. endwin is not valid with any other yearopt values.
When yearopt = 3, endwin is an absolute date in $HOROLOG date format that indicates the end date of the sliding window.
When yearopt = 5, endwin is a numeric value that indicates the end year of the sliding window expressed as the number of years past the current year. The sliding window always ends on December 31st of the year specified in endwin. If endwin is not specified, it defaults to December 31st of the year 100 years after startwin.
If endwin is omitted (or specified as -1) the effective sliding window will be 100 years long. The endwin value of -1 is a special case that always returns a date value, even when higher and lower endwin values return erropt. For this reason, it is preferable to omit endwin when specifying a 100-year window, and to avoid the use of negative endwin values.
If you supply both startwin and endwin, the sliding window they specify must not have a duration of more than 100 years.
mindate
An expression that specifies the lower limit of the range of valid dates (inclusive). Can be specified as a $HOROLOG integer date count (for example, 1/1/2013 is represented as 62823) or a $HOROLOG string value. You can include or omit the time portion of a $HOROLOG date string (for example “62823,43200”), but only the date portion of mindate is parsed. Specifying an hdate value earlier than mindate generates a <VALUE OUT OF RANGE> error.
The following are supported mindate values:
-
Positive integer: Most commonly mindate is specified as a positive integer to establish the earliest allowed date as some date after December 31, 1840. For example, a mindate of 21550 would establish the earliest allowed date as January 1, 1900. The highest valid value is 2980013 (December 31, 9999).
-
0: specifies the minimum date as December 31, 1840. This is the DateMinimum property default.
-
Negative integer -2 or larger: specifies a minimum date counting backwards from December 31, 1840. For example, a mindate of -14974 would establish the earliest allowed date as January 1, 1800. Negative mindate values are only meaningful if the DateMinimum property of the current locale has been set to an equal or greater negative number. The lowest valid value is -672045.
-
If omitted (or specified as -1), mindate defaults to the DateMinimum property value for the current locale, unless one of the following is true: If localeopt=1, the mindate default is 0. If localeopt is unspecified and dformat=3, the mindate default is 0. If localeopt is unspecified and dformat is 18, 19, 20, or 21 (Islamic date formats) the mindate default is 0.
You can get and set the DateMinimum property as follows:
SET min=##class(%SYS.NLS.Format).GetFormatItem("DateMinimum")
WRITE "initial DateMinimum value is ",min,!
Permit18thCenturyDates
SET x=##class(%SYS.NLS.Format).SetFormatItem("DateMinimum",-51498)
SET newmin=##class(%SYS.NLS.Format).GetFormatItem("DateMinimum")
WRITE "set DateMinimum value is ",newmin,!!
RestrictTo19thCenturyDates
WRITE $ZDATE(-13000,1,,,,,-14974),!!
ResetDateMinimumToDefault
SET oldmin=##class(%SYS.NLS.Format).SetFormatItem("DateMinimum",min)
WRITE "reset DateMinimum value from ",oldmin," to ",min
You may specify mindate with or without maxdate. Specifying a mindate larger than maxdate generates an <ILLEGAL VALUE> error.
maxdate
An expression that specifies the upper limit of the range of valid dates (inclusive). Can be specified as a $HOROLOG integer date count (for example, 1/1/2100 is represented as 94599) or a $HOROLOG string value. You can include or omit the time portion of the $HOROLOG date (for example “94599,43200”), but only the date portion of maxdate is parsed.
If maxdate is omitted or if specified as -1, the maximum date limit is obtained from the DateMaximum property of the current locale, which defaults to the maximum permissible value for the date portion of $HOROLOG: 2980013 (corresponding to December 31, 9999 CE). However, the application of the DateMaximum property is governed by the localeopt setting. When localeopt=1 (which is the default for dformat=3) the date maximum default is the ODBC value (2980013), regardless of the current locale setting. Islamic date formats also take the ODBC default. The maximum date for Thai date format (dformat=13) is $HOROLOG 2781687 which corresponds to 31/12/9999 BE.
Specifying a hdate larger than maxdate generates a <VALUE OUT OF RANGE> error.
Specifying a maxdate larger than 2980013 generates an <ILLEGAL VALUE> error.
You may specify maxdate with or without mindate. Specifying a maxdate smaller than mindate generates an <ILLEGAL VALUE> error.
erropt
Specifying a value for this argument suppresses errors associated with invalid or out of range hdate values. Instead of generating <ILLEGAL VALUE> or <VALUE OUT OF RANGE> errors, the $ZDATE function returns the erropt value.
-
Validation: InterSystems IRIS performs canonical numeric conversion on hdate. Parsing of an hdate string halts at the first non-numeric character. Therefore, an hdate string such as 64687AD is the same as 64687. A non-numeric date (including the null string) evaluates to 0. Thus an empty string hdate returns the $HOROLOG initial date: December 31, 1840. However, if hdate does not evaluate to an integer (contains a non-zero fractional number) it generates an <ILLEGAL VALUE> error.
-
Range: hdate must evaluate to an integer within the mindate/maxdate range. By default, date values greater than 2980013 or less than 0 generate a <VALUE OUT OF RANGE> error. By setting mindate to a negative number, you can extend the range of valid dates before December 31, 1840. However, for dformat 18, 19, 20, or 21 (Hijri Islamic calendar) dates, any date prior to -445031 generates an <ILLEGAL VALUE> error, even if mindate is set to an earlier date.
The erropt argument only suppresses errors generated due to invalid or out of range values of hdate. Errors generated due to invalid or out of range values of other arguments will always generate errors whether or not erropt has been supplied. For example, an <ILLEGAL VALUE> error is always generated when $ZDATE specifies a sliding window where endwin is earlier than startwin. Similarly, an <ILLEGAL VALUE> error is generated when maxdate is less than mindate.
Invalid Date Handling with ZDateNull
The behavior of $ZDATE when given an invalid value for hdate can be set using ZDateNull. To set this behavior for the current process, use the ZDateNull()Opens in a new tab method of the %SYSTEM.ProcessOpens in a new tab class. The system-wide default behavior can be established by setting the ZDateNullOpens in a new tab property of the Config.MiscellaneousOpens in a new tab class. $ZDATE can either issue an error, or return a null value.
The system-wide default behavior is configurable. Go to the Management Portal, select System Administration, Configuration, Additional Settings, Compatibility. View and edit the current setting of ZDateNull. The default is “false”, meaning that $ZDATE returns an error.
localeopt
This Boolean argument specifies either the user’s current locale definition or the ODBC locale definition as the source for defaults for the locale-specified arguments dformat, monthlist, yearopt, mindate and maxdate:
-
If localeopt=0, all of these arguments take the current locale definition defaults.
-
If localeopt=1, all of these arguments take the ODBC defaults.
-
If localeopt is not specified, the dformat argument determine the default for these arguments. If dformat=3, the ODBC defaults are used. If dformat is 18, 19, 20, or 21 the Islamic date format defaults are used, regardless of the current locale definition. For all other dformat values, the current locale definition defaults are used. Refer to the dformat description for further details.
The ODBC locale cannot be changed; it is used to format date strings that are portable between InterSystems IRIS processes that have made different National Language Support (NLS) choices. If localeopt=1, the ODBC locale date definitions are as follows:
-
Date format defaults to 3. Therefore, if dformat is undefined or -1, date format 3 is used.
-
Date separator defaults to "/". However, date format defaults to 3, which always uses "-" as the date separator.
-
Year option defaults to 4 digits.
-
Date minimum and maximum: 0 and 2980013 ($HOROLOG date count).
-
English month names, month abbreviations, weekday names, and weekday abbreviations are used.