第八十五章 Caché 函数大全 $ZDATETIME 函数

第八十五章 Caché 函数大全 $ZDATETIME 函数

验证日期和时间,并将其从内部格式转换为指定的显示格式。

大纲

$ZDATETIME(hdatetime,dformat,tformat,precision,monthlist,yearopt,startwin,endwin,mindate,maxdate,erropt,localeopt)
$ZDT(hdatetime,dformat,tformat,precision,monthlist,yearopt,startwin,endwin,mindate,maxdate,erropt,localeopt)

参数

  • hdatetime 日期和时间值,以内部日期和时间格式指定。请参阅下面的hdatetime。
  • dformat 可选—一个整数代码,用于指定返回日期值的格式。请参阅下面的dformat。
  • tformat 可选—一个整数代码,指定返回的时间值的格式。请参阅下面的tformat。
  • precision 可选—一个整数,指定返回的时间值的精度的小数位数(小数秒)。请参见下面的精度。
  • monthlist 可选-字符串或变量名称,用于指定一组月份名称。该字符串必须以分隔符开头,并且其12个条目必须由该分隔符分隔。请参阅下面的月列表。
  • yearopt 可选—整数代码,用于指定是将年表示为两位数字还是四位数字的值。请参阅下面的yearopt。
  • startwin 可选-滑动窗口的开始,其间日期用两位数的年份表示。请参阅下面的startwin。
  • endwin 可选-滑动窗口的末尾,其间用两位数的年份表示日期。请参阅下面的endwin。
  • mindate 可选-有效日期范围的下限。指定为$HOROLOG整数日期计数,0表示1840年12月31日。可以指定为正整数或负整数。请参阅下面的提示。
  • maxdate 可选-有效日期范围的上限,指定为整数$HOROLOG日期计数。请参阅下面的maxdate。
  • erropt 可选-当hdatetime无效时返回的表达式。为该参数指定值将抑制与无效或超出范围的hdatetime值相关的错误代码。 $ZDATETIME不会发出错误消息,而是返回错误。请参阅下面的错误提示。
  • localeopt 可选-布尔值标志,用于指定要用于dformat,tformat,monthlist,yearopt,mindate和maxdate默认值以及其他日期和时间特征的语言环境:localeopt = 0:当前的语言环境属性设置确定这些参数默认值。localeopt = 1:ODBC标准语言环境确定这些参数默认值。未指定localeopt:dformat值确定这些参数默认值。如果dformat = 3,则使用ODBC默认值。否则,将使用当前的语言环境属性设置。请参阅下面的localeopt。

指定参数值之间的省略参数由占位符逗号指示。末尾的占位符逗号不是必需的,但允许使用。逗号之间允许有空格,以指示省略的参数。

描述

$ZDATETIME验证指定的日期和时间,并将其从$HOROLOG$ZTIMESTAMP内部格式转换为几种替代的日期和时间显示格式之一。返回的确切值取决于指定的参数。

  • $ZDATETIME(hdatetime)以默认显示格式返回当前语言环境的日期和时间。
  • $ZDATETIME(hdatetime,dformat,tformat,precision,monthlist,yearopt,startwin,endwin,mindate,maxdate)以dformat和tformat指定的显示格式返回日期和时间,并由您指定的其他参数进一步定义。有效日期范围可能受mindate和maxdate参数限制。

参数

hdatetime

日期和时间,指定为内部格式值。 Caché内部格式将日期表示为从任意起点(1840年12月31日)开始的天数,并且将时间表示为当天的秒数。 hdatetime值必须是以下格式之一的字符串:

  • $HOROLOG:两个无符号整数,以逗号分隔。第一个是指定日期(以天为单位)的整数,第二个是指定时间(以秒为单位)的整数。
  • $ZTIMESTAMP:两个用逗号分隔的无符号数字:第一个是指定日期(以天为单位)的整数,第二个是指定时间(以秒为单位)的数字。时间值在小数点右边最多可以有9位精度(分数秒)。

可以将hdatetime指定为字符串值,变量或表达式。

如果hdatetime仅指定日期部分的值且不指定逗号,则仅返回日期。如果hdatetime指定日期部分的值后跟一个逗号,但没有时间值,则系统提供的时间值为00:00:00。

默认情况下,最早的有效hatetime日期为0(1840年12月31日)。默认情况下,日期限制为正整数,因为DateMinimum属性默认为0。如果当前语言环境的DateMinimum属性设置为更大或等于负整数,则可以将较早的日期指定为负整数。有效的最低DateMinimum值的最低值是-672045,对应于0001年1月1日。Caché使用了多功的格里高利历,该格里高利历将其投影回“ Year 1”,符合ISO 8601标准。这在一定程度上是因为公历是在不同国家的不同时间采用的。例如,许多欧洲大陆在1582年采用了它;大不列颠及美国在1752年采用了该日期。因此,在当地采用格里高利历的时间是不早于当时基于当地历法记录的历史日期。有关1840年之前的日期的更多详细信息,请参考mindate参数。

无效和超出范围的hdatetime值以及由此产生的错误在erropt参数中进行了描述。

dformat

返回日期的格式。有效值为:

含义
1 MM/DD/[YY]YY(07/01/97或03/27/2002)-美国数字格式。日期分隔符(/或.)。取自当前区域设置。
2 DD Mmm [ YY ]YY (01 Jul 97 or 27 Mar 2002)
3 YYYY-MM-DD(1997-07-01)— ODBC格式。默认情况下,此格式与您当前的语言环境设置无关,从而以ODBC标准交换格式指定日期和时间。 (下面的tformat部分中描述了ODBC时间格式的默认值。)要将当前的日期和时间区域设置与该格式一起使用,请将localeopt设置为0。
4 DD/MM/[YY]YY (01/07/97 or 27/03/2002) 欧洲数字格式。日期分隔符(/或。)取自当前的语言环境设置。
5 Mmm [D]D, YYYY (Jul 1, 1997 or Mar 27, 2002)
6 Mmm [D]D YYYY (Jul 1 1997 or Mar 27 2002)
7 Mmm DD [YY]YY (Jul 01 97 or Mar 27 2002)
8 YYYYMMDD (19970701 or 20020327) 数值格式
9 Mmmmm [D]D, YYYY (July 1, 1997 or March 27, 2002)
10 W(2)-一周中的天数,从0(星期日)到6(星期六)编号。与$SYSTEM.SQL.DAYOFWEEK()方法进行比较。
11 Www(Tue)-缩写的日期名称
12 Wwwwww (Tuesday))—全天名称
13 [D]D/[M]M/YYYY (1/7/2549 or 27/11/2549) 泰文日期格式。除无前导零外,日和月与欧洲用法相同。该年是佛教时代(BE)年,通过在公历年中增加543年而得出。
14 nnn(354)-年的天数
15 DD/MM/[YY]YY (01/07/97 or 27/03/2002) 欧洲格式(与dformat = 4相同)。日期分隔符(/或。)取自当前的语言环境设置。
16 YYYYc[M]Mc[D]Dc —日文日期格式。年,月和日的编号与其他日期格式相同;前导零被省略。在年,月和日编号之后插入“年”,“月”和“日”的日语字符(在此处显示为c)。这些字符是Year = $CHAR(24180),Month = $CHAR(26376)和Day = $CHAR(26085)
17 YYYYc [M]Mc [D]Dc —日文日期格式。与dformat 16相同,除了在“ year”和“ month”日语字符之后插入空格。
18 [D]D Mmmmm YYYY - 具有完整月份名称的表格回历(伊斯兰)日期格式。省略了日期前导零。包括年份前导零。教堂日期-445031(公元07/19/0622)= 1穆罕默德0001。
19 [D]D [M]M YYYY 带月号的表格回历(伊斯兰)日期格式。日和月的前导零被省略;包括年份前导零。教堂日期-445031(西元07/19/0622)= 1 1 0001。
20 [D]D Mmmmm YYYY —观察到的回历(伊斯兰)日期格式,并带有完整的月份名称。默认为表格回历(dformat 18)。要覆盖表格计算,请使用%Calendar.Hijri类添加对新月新月的观测。
21 [D]D [M]M YYYY —观察到的回历(伊斯兰)日期格式和月数。默认为表格回历(dformat 19)。要覆盖表格计算,请使用%Calendar.Hijri类添加对新月新月的观测。
-1 从用户的语言环境fmt.DateFormat获取有效的dformat值,其中fmt是与当前进程关联的## class(%SYS.NLS.Format)的实例。如果不指定dformat,则这是默认行为。有关更多详细信息,请参见“可自定义的日期和时间默认值”。
-2 $ZDATETIME返回一个整数,指定距特定于平台的原始日期/时间的秒数。这是time()库函数返回的值,如ISO C编程语言标准中所定义。例如,在兼容POSIX的系统上,此值是从1970年1月1日00:00:00 UTC开始的秒数。允许输入小数秒,但可以忽略。 (当前,此日期转换可能具有针对tformat值5、6、7和8描述的“本地时变边界日”时间转换异常。)支持以下特定于平台的格式:32位Linux:带符号的32-位整数; 64位Linux:带符号的64位整数; Windows:无符号64位整数。请参考《CachéMultiValue基本参考》中的MultiValue Basic SYSTEM(99)函数。 tformat,precision,monthlist,yearopt,startwin和endwin参数将被忽略。
-3 $ZDATETIME采用以$HOROLOG内部格式指定的日期时间值,将该值从本地时间转换为UTC通用时间,并以相同的内部格式返回结果值。 tformat,monthlist,yearopt,startwin和endwin参数将被忽略。 $ZDATETIMEH执行相反的操作。 (当前,此日期转换具有针对tformat值5、6、7和8描述的时间转换异常。这可能会影响1970年之前的日期,2038年之后的日期以及本地时变边界天,例如开始日期或结束日期夏令时的日期。)。

其中

语法 含义
YYYY YYYY是四位数的年份。 [YY]如果hdatetime落在活动窗口内达两位数年份,则YY为两位数年份;否则为四位数年份。
MM 两位数的月份:01到12。[M] M表示在月份1到9中省略了前导零。
DD 两位数的日期:01到31。[D] D表示第1到9天省略了前导零。
Mmm 从当前语言环境的MonthAbbr属性中提取的月份缩写。可以从指定为$ZDATETIME的monthlist参数的可选列表中提取备用月份的缩写(或任何长度的名称)。 MonthAbbr的默认值是:“Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec”
Mmmmm 由当前语言环境的MonthName属性指定的月份的全名。默认值为:“January February March ... November December”
W 数字0-6表示星期几:Sunday=0, Monday=1, Tuesday=2, etc.
Www 工作日名称缩写,由当前语言环境的WeekdayAbbr属性指定。默认值为:“Sun Mon Tue Wed Thu Fri Sat”
Wwwwww 由当前语言环境的WeekdayName属性指定的工作日全名。默认值为:“Sunday Monday Tuesday ... Friday Saturday”
nnn 指定年份的天数,始终为三位数,如有必要,前导零。值是001到365(leap年时是366)。

dformat Default

如果省略dformat或将其设置为-1,则dformat的默认值取决于localeopt参数和NLS DateFormat属性:

  • 如果localeopt = 1,则dformat的默认值为ODBC格式。 tformat,monthlist,yearopt,mindate和maxdate参数也设置为ODBC格式。这与设置dformat = 3相同。”
  • 如果localeopt = 0或未指定,则dformat默认值来自NLS DateFormat属性。如果DateFormat = 3,则dformat的默认值为ODBC格式。但是,DateFormat = 3不会影响在当前NLS语言环境定义中指定的monthlist,yearopt,mindate和maxdate参数默认值。

若要确定语言环境的默认日期格式,请调用GetFormatItem()NLS类方法:

WRITE ##class(%SYS.NLS.Format).GetFormatItem("DateFormat")

欧洲日期格式(dformat = 4,DD / MM / YYYY顺序)是许多(但不是全部)欧洲语言的默认格式,包括英式英语,法语,德语,意大利语,西班牙语和葡萄牙语(使用“ /”日期分隔符)字符),以及捷克语(csyw),俄语(rusw),斯洛伐克语(skyw),斯洛文尼亚语(svnw)和乌克兰语(ukrw)(使用“。” DateSeparator字符)。

dformat Settings

如果dformat为3(ODBC日期格式),则ODBC格式默认值也用于monthlist,yearopt,minate和maxdate参数默认值。当前的语言环境默认值将被忽略。

如果dformat为-1、1、4、13或15(数字日期格式),则$$ZDATETIME使用当前语言环境的DateSeparator属性的值作为月,日和年之间的分隔符。当dformat为3时,使用ODBC日期分隔符(“-”)。对于所有其他dformat值,空格用作日期分隔符。 DateSeparator的英语默认值为“ /”,并且所有文档都使用此分隔符。

如果dformat是11或12(日期名称)且localeopt = 0或未指定,则日期名称值来自当前的语言环境属性。如果localeopt = 1,则日期名称来自ODBC语言环境。若要确定语言环境的默认工作日名称和工作日缩写,请调用以下NLS类方法:

  WRITE ##class(%SYS.NLS.Format).GetFormatItem("WeekdayName"),!
  WRITE ##class(%SYS.NLS.Format).GetFormatItem("WeekdayAbbr"),!

如果dformat为16或17(日语日期格式),则返回的日期格式与语言环境设置无关。可以从任何UnicodeCaché实例返回日语格式的日期。在8位Caché实例上,将dformat指定为16或17会导致错误。

如果dformat为18、19、20或21(伊斯兰日期格式)且未指定localeopt,则参数默认为伊斯兰默认值,而不是当前的语言环境默认值。 monthlist参数默认为阿拉伯语月份名称,并用拉丁字符音译。 tformat,yearopt,mindate和maxdate参数默认为ODBC默认值。日期分隔符默认为回教默认值(一个空格),而不是ODBC默认值或当前区域设置的DateSeparator属性值。如果localeopt = 0,则将当前语言环境属性默认值用于这些参数。如果localeopt = 1,则将ODBC默认值用于这些参数。

tformat

一个数字值,指定您要表达时间值的格式。支持的值为:

描述
-1 从当前语言环境的TimeFormat属性获取有效的tformat值,默认为1。这是默认行为,如果未为除3之外的所有dformat值指定tformat。
1 以“ hh:mm:ss”(24小时制)的形式表示时间。
2 以“ hh:mm”的形式表示时间(24小时制)
3 以“ hh:mm:ss [AM / PM]”的形式表示时间(12小时制)
4 以“ hh:mm [AM / PM]”的形式表示时间(12小时制)
5 以“ hh:mm:ss +/- hh:mm”的形式表示时间(24小时制)。时间以当地时间表示。加(+)或减(–)后缀显示系统定义的本地时间与协调世界时(UTC)的偏移量。减号(-hh:mm)表示本地时间早于格林威治子午线(向西)乘以返回的小时和分钟偏移量。加号(+ hh:mm)表示本地时间晚于格林威治子午线(向东),返回的时差为小时和分钟。进一步的细节在下面描述。
6 以“ hh:mm +/- hh:mm”的形式表示时间(24小时制)。时间以当地时间表示。加(+)或减(–)后缀显示系统定义的本地时间与协调世界时(UTC)的偏移量。减号(-hh:mm)表示本地时间早于格林威治子午线(向西)乘以返回的小时和分钟偏移量。加号(+ hh:mm)表示本地时间晚于格林威治子午线(向东),返回的时差为小时和分钟。进一步的细节在下面描述。
7 以“ hh:mm:ssZ”(24小时制)的形式表示时间。后缀“ Z”表示该时间表示为协调世界时(UTC),而不是本地时间。
8 以“ hh:mmZ”(24小时制)的形式表示时间。后缀“ Z”表示时间表示为协调世界时(UTC),而不是本地时间。
9 对于MultiValue支持。与tformat 1(“ hh:mm:ss” 24小时制)相同,其数值介于0到86399之间。还接受负时间值和大于86399的时间值,如下所述。
10 对于MultiValue支持。与tformat 2(“ hh:mm” 24小时制)相同,其数值介于0到86399之间。还接受负时间值和大于86399的时间值,如下所述。

如果省略tformat或将其设置为-1,则tformat的默认值取决于localeopt参数和NLS TimeFormat属性:

对于除3、18、19、20和21以外的所有dformat值,所有时间格式均默认为当前语言环境定义TimeSeparatorDecimalSeparator属性值。对于dformat = 3(ODBC日期格式)和dformat = 18、19、20或21(伊斯兰日期格式),时间分隔符为冒号(:),DecimalSeparator为句点(),而与当前语言环境属性值无关。这些默认值可以通过设置localeopt来覆盖。

若要确定语言环境的默认时间属性,请调用GetFormatItem()NLS类方法:

DHC-APP>WRITE ##class(%SYS.NLS.Format).GetFormatItem("TimeFormat")
1
DHC-APP>WRITE ##class(%SYS.NLS.Format).GetFormatItem("TimeSeparator")
:
DHC-APP>WRITE ##class(%SYS.NLS.Format).GetFormatItem("DecimalSeparator")
.

对于tformat值1-4(返回本地时间),日期与时间用空格分隔。对于5到8的tformat值,日期与时间之间用字母“T”分隔。

12–hour Clock (tformat 3 and 4)

在12小时制的时钟格式中,早上和晚上由时间后缀表示,此处显示为AMPM。若要确定语言环境的默认时间后缀,请调用GetFormatItem()NLS类方法,如下所示:

DHC-APP>WRITE ##class(%SYS.NLS.Format).GetFormatItem("AM")
AM
DHC-APP> WRITE ##class(%SYS.NLS.Format).GetFormatItem("PM")
PM

对于除3、18、19、20和21以外的所有dformat值,AM和PM属性默认为当前区域设置定义。对于dformat = 3(ODBC日期格式)和dformat = 18、19、20或21(伊斯兰日期格式),无论当前语言环境属性值如何,时间后缀始终为“ AM”和“ PM”。除日语语言环境jpww之外,所有语言环境的AM和PM属性默认值为“ AM”和“ PM”。

默认情况下,除日语语言环境(jpnw,jpuw,jpww,zdsw,zdtw,zduw),葡萄牙语(ptbw),俄语(rusw)和乌克兰语(ukrw)外,所有其他语言环境的Midnight和Noon均表示为“ MIDNIGHT”和“ NOON” )。

但是,当dformat = 3时,$ZDATETIME始终使用ODBC标准值,而不管语言环境的默认设置如何。

Local Time (tformat 5, 6, 7, and 8)

当tformat设置为5或6时,hdatetime输入值假定为本地日期和时间,并显示为本地日期和时间。如果hdatetime是当前本地日期和时间($HOROLOG),则更改$ZTIMEZONE将更改当前进程的当前日期和时间。

偏移后缀将本地时变设置指定为相对格林威治子午线的正偏移或负偏移,以小时和分钟为单位。请注意,此本地时变不一定是时区偏移量。例如,美国东部时区在格林威治(-5:00)西部5小时,但是本地时区(夏令时)将时区时间偏移一小时到-04:00。设置$ZTIMEZONE更改$ZDATETIME($HOROLOG,1,5)返回的当前处理日期和时间,但不更改系统本地时间变化设置。

注意:tformat 5或6返回本地时间与UTC时间的偏移量。这既不是当地时区的偏移量,也不是当地时间与格林威治英国当地时间的比较。格林威治标准时间(GMT)一词可能令人困惑;格林威治英国当地时间与冬季UTC相同。在夏季,它与UTC的差异为一小时。这是因为应用了称为英国夏令时的本地时间变体。

以下示例显示了tformat 5值如何受到操作系统的本地时间变化设置以及更改当前进程的时区的影响。 (请注意,此示例检查程序执行期间是否出现本地时间变化边界):

/// d ##class(PHA.TEST.Function).ZDATETIME()
ClassMethod ZDATETIME()
{
LocalDatetimeOffset
    SET dst=$SYSTEM.Util.IsDST()
    SET local=$ZDATETIME($HOROLOG,1,5)
    WRITE local," 是本地日期/时间和偏移量",!!
    SET off=$PIECE(local,"+",2)
    IF off="" {
        SET off=$PIECE(local,"-",2)
        WRITE "-",off," 是本地偏移量",!
    } ELSE {
        WRITE "+",off," 是本地偏移量",!
    }
    SET tz=$ZTIMEZONE
    WRITE tz/60," 是本地时区偏移量,以小时为单位",!!
    IF dst=1 {
        WRITE "夏令时生效, ",off," 偏移量不是 ",tz/60," 时区偏移",!
    } ELSEIF dst=0 {
        WRITE " 夏令时没生效, 偏移量 ",off,"=时区 ",tz/60,!
    } ELSE {
        WRITE " 无法确定DST设置",!
    }
ChangeTimezoneForCurrentProcess
    SET $ZTIMEZONE=tz+180
    WRITE !,"将流程时区向西更改3小时",!
    WRITE $ZDATETIME($HOROLOG,1,5)," 是新的本地日期/时间和偏移量",!
    WRITE "请注意,时间已更改,但偏移量未更改"
    SET $ZTIMEZONE=tz
ConfirmNoDSTBoundary
    SET dst2=$SYSTEM.Util.IsDST()
    GOTO:dst'=dst2 LocalDatetimeOffset
}
DHC-APP>d ##class(PHA.TEST.Function).ZDATETIME()
11/12/2020T11:01:47+08:00 是本地日期/时间和偏移量
 
+08:00 是本地偏移量
-8 是本地时区偏移量,以小时为单位
 
 夏令时没生效, 偏移量 08:00=时区 -8
 
将流程时区向西更改3小时
11/12/2020T08:01:47+08:00 是新的本地日期/时间和偏移量
请注意,时间已更改,但偏移量未更改

当tformat设置为7或8时,hdatetime输入值假定为本地日期和时间。时间更改为与UTC时间相对应(使用本地时区设置计算)。返回的日期也可以更改(如有必要)以与此UTC时间值相对应。因此,返回的日期可能与本地日期不同。

注意:
涉及dformat值-2和-3以及tformat值7和8以及由tformat值5和6生成的UTC偏移的转换具有以下与平台有关的异常:

  • 从本地时间到UTC时间的转换取决于本地时变边界行为,这在不同的操作系统平台上可能有所不同:

当本地时钟向前移动时(夏令时开始时为“春天向前”),本地时间将损失一个小时。此“丢失”小时是非法的本地时间值。 Caché $HOROLOG绝不能返回非法的本地时间值。但是,如果用户手动输入此非法本地时间值(例如,通过设置$HOROLOG),则$ZDATETIME转换结果是不确定的,并且高度依赖于平台。

  • 当地时间和UTC时间之间的转换必须使用在指定年份和位置有效的当地时变规则。由于这些规则是由当地法律建立的,可能在过去有所更改,并且将来可能会更改,因此$ZDATETIME转换取决于操作系统平台编码的规则的完整性和准确性。对未来的预测必须使用当前规则,并且这些规则可能会更改。

  • 当地时间和UTC时间之间的转换取决于操作系统平台支持的日期范围:

如果日期早于平台支持的最早日期,则Caché将使用1902–01–01的标准时间偏移(如果平台支持此日期)。如果平台不支持日期1902-01-01,则Caché使用1970-01-01的标准时间偏移。任何本地时变偏移量(例如夏令时)都将被忽略。

如果日期晚于平台支持的最新日期,则Caché会计算2010-01-01至2037-12-31范围内的对应日期,并使用该对应日期的标准时间偏移。该算法应为2100-02-28年之内的日期提供准确的时间偏移,前提是有关日期/时间遵守的法律将来没有变化。

注意:$ZDATETIME无法确定hdatetime输入值是UTC时间还是本地时间。因此,请勿将tformat值5、6、7或8与UTC中已经存在的hdatetime一起使用,例如$ZTIMESTAMP值。如果在将时间转换回本地时间的操作中使用了tformat 7或8转换的输出,请注意,本地到UTC转换中的日期可能已更改。

MultiValue Time (tformat 9 and 10)

提供了时间格式9和10以支持MultiValue。对于在ObjectScript允许范围内的所有时间值:0到86399,它们与tformats 1和2相同。在此范围内,它们以与其他时间格式相同的方式处理小数秒。与其他时间格式一样,-0被视为0。

时间格式9和10接受负数值,并返回相应的负时间值。 tformat 9返回负时间值,即“ -hh:mm:ss”(24小时制)。 tformat 10返回负时间值,即“ -hh:mm”(24小时制)。对于时间格式10,“ – 59.9”返回“ –00:00”,“ – 60”返回“ –00:01”。负小数秒总是被截断。因此,–4.9返回“ –00:00:04”; “ –0”和“ –0.9”都返回正值“ 00:00:00”。

时间格式9和10接受大于86399的数值,并返回相应的时间。因此86400返回“ 24:00:00”,而400000返回“ 111:06:40”。对于0到86399范围内的值,返回小数秒。对于86400或更大的值,小数秒将被截断。

如果指定了精度,并且指定了超出Caché范围的时间值,则任何指定的分数秒都会被截断,并且分数精度部分将返回零。

precision

一个整数值,指定用于表示时间的小数秒精度的小数位数。也就是说,如果输入精度值3,则$ZDATETIME会将秒数显示到小数点后三位。如果输入精度值9,则$ZDATETIME将显示秒数,保留到小数点后九位。此参数指定要返回的小数位数。精确的有意义位数的实际数量由hdatetime源确定。例如,$HOROLOG不返回小数秒; $ZTIMESTAMP和$NOW()返回小数秒。

DHC-APP>W $zdt($h,,,3)
11/12/2020 15:25:44.000
DHC-APP>W $zdt($h,,,9)
11/12/2020 15:26:01.000000000

支持的值如下:

-1:从当前语言环境的TimePrecision属性获取精度值,该值默认为0。这是默认行为,如果未指定precision。

大于或等于零(0)的n值导致将时间表示为n个小数位。

仅当hdatetime格式可以包含小数时间值($ZTIMESTAMP格式),并且所选的tformat选项包括秒时,Precision才适用。尾随零不会被抑制。如果指定的精度超过系统上可用的精度,则精度的多余数字将作为尾随零返回。您可以使用Normalize()方法来抑制多余的尾随零,如以下示例所示,其指定精度为9:

DHC-APP>WRITE $ZDATETIME($ZTIMESTAMP,3,,9),!
2020-11-12 07:27:05.197000000
 
DHC-APP>WRITE $ZDATETIME($ZTIMESTAMP,3),!
2020-11-12 07:27:14
 
DHC-APP> WRITE ##class(%TimeStamp).Normalize($ZDATETIME($ZTIMESTAMP,3,,9))
2020-11-12 07:27:23.968

若要确定语言环境的默认时间精度,请调用GetFormatItem()NLS类方法:

DHC-APP> WRITE ##class(%SYS.NLS.Format).GetFormatItem("TimePrecision")
0

可以将语言环境的TimePrecision设置为所需的数字位数,最大为15。

monthlist

该表达式可解析为月份名称或月份名称缩写的字符串,以分隔符分隔。 monthlist中的名称替换了来自当前语言环境的MonthAbbr属性的默认月份缩写值或来自MonthName属性的月份名称值。

仅当dformat为2、5、6、7、9、18或20时,monthlist才有效。如果dformat为任何其他值,$ZDATE将忽略monthlist。

月列表字符串具有以下格式:

  • 字符串的第一个字符是定界符(通常为空格)。同一分隔符必须出现在月份列表的第一个月份名称之前和每个月份名称之间。可以指定任何单字符定界符;该分隔符出现在返回日期值的月,日和年部分之间,这就是为什么通常使用空格作为首选字符的原因。

  • 月份名称字符串应包含十二个分隔值,分别对应于一月到十二月。可以指定多于或少于十二个月的名称,但是如果没有对应于hdatetime中月份的月份名称,则会生成错误。

如果省略monthlist或将monthlist值指定为-1,则$ZDATETIME使用在当前语言环境的MonthAbbr或MonthName属性中定义的月份名称列表,除非满足以下条件之一:如果localeopt = 1,则月份列表默认值为ODBC月列表(英文)。如果未指定localeopt且dformat为18或20(伊斯兰日期格式),则月列表默认值为伊斯兰月份列表(使用拉丁字母表示的阿拉伯名称),忽略MonthAbbrMonthName属性值。

若要确定语言环境的默认月份名称和月份缩写,请调用GetFormatItem()NLS类方法:

DHC-APP>WRITE ##class(%SYS.NLS.Format).GetFormatItem("MonthAbbr"),!
 Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
 
DHC-APP>WRITE ##class(%SYS.NLS.Format).GetFormatItem("MonthName"),!
 January February March April May June July August September October November December

yearopt

使用dformat值0、1、2、4、7或15,这是一个数字代码,用于指定将年份显示为两位数值的时间窗口。 yearopt可以是:

描述
-1 从当前语言环境的YearOption属性获取有效的yearopt值,该值默认为0。如果未指定yearopt,则这是默认行为。
0 除非有特定于过程的滑动窗口(通过%DATE实用程序建立),否则用两位数字表示20世纪的日期(1900年至1999年)。如果这样的窗口有效,请仅将落在滑动窗口中的那些日期表示为两位数年份。用20位数字表示所有20世纪以外或特定于过程的滑动窗口之外的日期。
1 代表20世纪的日期用两位数的年份表示,其他所有日期用4位数的年份表示。
2 用两位年份表示所有日期。
3 这些日期用两位数的年份表示由startwin和(可选)endwin定义的滑动时间范围内的日期。用四位数字的年份表示所有其他日期。当yearopt = 3时,startwin和endwin是$HOROLOG格式的绝对日期。
4 用四位数年份表示所有日期。
5 所有日期都用两位数的年份表示,这些日期都落在startwin和(可选)endwin定义的滑动窗口内。用四位数字的年份表示所有其他日期。当yearopt = 5时,startwin和endwin是相对年份。
6 用两位数字年份代表当前世纪的所有日期,而用四位数年份代表所有其他日期。

若要确定语言环境的默认年份选项,请调用GetFormatItem()NLS类方法:

DHC-APP> WRITE ##class(%SYS.NLS.Format).GetFormatItem("YearOption")
0

如果省略yearopt或将yearopt值指定为-1,则$ZDATETIME使用当前语言环境的YearOption属性,除非满足以下条件之一:如果localeopt = 1,则yearopt默认为ODBC year选项。如果localeopt = 0或未指定,并且dformat是18、19、20或21(伊斯兰日期格式),则yearopt的默认值为ODBC year选项(4位数字的年份);否则,默认值为ODBC年。回教日期将忽略YearOption属性值。

startwin

一个数字值,指定滑动窗口的开始,在此期间,日期必须用两位数的年份表示。当使用的yearopt为3或5时,必须提供startwin。startwin不适用于任何其他yearopt值。

yearopt = 3时,startwin是$HOROLOG日期格式的绝对日期,指示滑动窗口的开始日期。

yearopt = 5时,startwin是一个数字值,表示滑动窗口的开始年份,表示为当前年份之前的年数。滑动窗口始终从startwin中指定的一年的1月1日开始。

endwin

一个数字值,指定滑动窗口的结束,在此期间内,日期用两位数的年份表示。当yearopt为3或5时,您可以选择提供endwin。endwin不适用于任何其他yearopt值。

yearopt = 3时,endwin是$HOROLOG日期格式的绝对日期,指示滑动窗口的结束日期。

yearopt = 5时,endwin是一个数字值,它表示滑动窗口的结束年份,表示为当前年份之后的年数。

如果yearopt = 5,则滑动窗口始终从startwin指定的年份的1月1日开始,到endwin指定的年份或隐含的结束年份(如果省略endwin)的12月31日结束。

如果省略endwin(或指定为-1),则有效滑动窗口将为100年。 endwin值为-1是一种特殊情况,即使较高和较低endwin值返回错误,也总是返回日期值。因此,最好在指定100年窗口时省略endwin,并避免使用负endwin值。

如果同时提供startwin和endwin,则它们指定的滑动窗口的持续时间不得超过100年。

mindate

该表达式指定有效日期范围的下限(含)。可以指定为$HOROLOG整数日期计数(例如,2013年1月1日表示为62823)或$HOROLOG字符串值。可以包括或忽略$HOROLOG日期的时间部分(例如“62823,43200”),但仅解析主意的日期部分。如果早于mindate指定hdatetime值,则会产生错误。

以下是受支持的提示值:

  • 正整数:最常见的正念指定为正整数,以建立最早的允许日期为1840年12月31日之后的某个日期。例如,正念21550会将最早的允许日期建立为1900年1月1日。最高有效值是2980013(9999年12月31日)。
  • 0:指定最小日期为1840年12月31日。这是DateMinimum属性的默认值。
  • 负整数-2或更大:指定从1840年12月31日开始倒数的最小日期。例如,记号-14974将建立最早的允许日期为1800年1月1日。负记号值仅在DateMinimum属性为时才有意义。当前语言环境已设置为等于或大于负数。最低有效值为-672045。
  • 如果省略(或指定为-1),则mindate默认为当前语言环境的DateMinimum属性值,除非以下条件之一为真:如果localeopt = 1,则minindate默认值为0。如果localeopt未指定且dformat = 3,预设值是0。如果未指定localeopt并且dformat是18、19、20或21(伊斯兰日期格式),则预设值是0。

可以获取并设置DateMinimum属性,如下所示:

/// d ##class(PHA.TEST.Function).ZDATETIM1()
ClassMethod ZDATETIME1()
{
    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 $ZDATETIME(-13000,1,,,,,,,-14974),!!
ResetDateMinimumToDefault
    SET oldmin=##class(%SYS.NLS.Format).SetFormatItem("DateMinimum",min)
    WRITE "reset DateMinimum value from ",oldmin," to ",min
}
DHC-APP>d ##class(PHA.TEST.Function).ZDATETIME1()
initial DateMinimum value is 0
set DateMinimum value is -51498
 
05/29/1805
 
reset DateMinimum value from -51498 to 0

可以指定有或没有maxdate的提示。指定大于maxdate的提示时,会产生错误。

ODBC Date Format (dformat 3)

DateMinimum属性的应用由localeopt设置控制。当localeopt = 1dformat = 3的默认值)时,无论当前的区域设置如何,最小日期均为0。因此,采用ODBC格式(dformat = 3),可以使用以下命令指定1840年12月31日之前的日期:

  • 指定早于指定日期的提示:
DHC-APP>WRITE $ZDATETIME(-30,3,,,,,,,-365)
1840-12-01
  • 指定早于指定日期的DateMinimum属性值,并设置localeopt = 0
DHC-APP>DO ##class(%SYS.NLS.Format).SetFormatItem("DateMinimum",-365)
 
DHC-APP>WRITE $ZDATETIME(-30,3,,,,,,,,,,0)
1840-12-01

maxdate

该表达式指定有效日期范围的上限(含)。可以指定为$HOROLOG整数日期计数(例如1/1/2100表示为94599)或$HOROLOG字符串值。可以包括或省略$HOROLOG日期的时间部分(例如“94599,43200”),但仅会解析maxdate的日期部分。

如果省略了maxdate或将其指定为-1,则最大日期限制是从当前语言环境的DateMaximum属性获取的,该属性默认为$HOROLOG日期部分的最大允许值:2980013(对应于9999年12月31日) )。但是,DateMaximum属性的应用由localeopt设置控制。当localeopt = 1dformat = 3的默认值)时,最大的默认日期是ODBC值(2980013),与当前的语言环境设置无关。回教日期格式也采用ODBC默认值。泰文日期格式(dformat = 13)的最大日期是$HOROLOG 2781687,对应于BE 31/12/9999。

指定大于maxdate的hdatetime会产生错误。

如果指定的最大日期大于2980013,则会产生错误。

可以指定maxdate或不指定。指定的maxdate小于mindate会生成错误。

erropt

为该参数指定值将抑制与无效或超出范围的hdatetime值相关的 or 错误。 $ZDATETIME函数将返回错误值,而不是生成或错误。

  • 验证:Caché在hdatetime上执行规范的数字转换。 hdatetime的日期和时间部分将分别进行分析。它解析遇到的第一个逗号作为日期/时间分隔符。其他逗号被视为非数字字符。

hdatetime字符串的每个部分的解析在第一个非数字字符处停止。因此,诸如64687AD,1234SECS的hdatetime与64687,1234相同。非数字日期或时间部分(包括空字符串)的计算结果为0。因此,空字符串hdatetime返回$HOROLOG初始日期:1840年12月31日。

但是,如果日期部分的值不等于整数(包含非零的小数),则会生成错误。

  • 范围:hdatetime的日期部分必须计算为mindate / maxdate范围内的整数。默认情况下,大于2980013或小于0的日期值会生成错误。通过将mindate设置为负数,可以扩展1840年12月31日之前的有效日期范围。但是,对于dformat 18、19、20或21(回教伊斯兰历)日期,-445031之前的任何日期都会生成即使将mindate设置为较早的日期,也会出现错误。

hdatetime的时间部分的值大于86399会产生 错误。 hdatetime时间值为负会生成 错误。

erropt参数仅抑制由于无效或超出hdatetime值范围而产生的错误。无论是否提供错误提示,由于其他参数无效或超出范围而产生的错误将始终产生错误。例如,当$ZDATETIME指定一个滑动窗口,其中endwin早于startwin时,总是生成错误。同样,当maxdate小于mindate时,会生成错误。

localeopt

此布尔值参数将用户的当前语言环境定义或ODBC语言环境定义指定为语言环境指定的参数dformat,tformat,monthlist,yearopt,minate和maxdate的默认值的来源:

  • 如果localeopt = 0,则所有这些参数均采用当前的语言环境定义默认值。
  • 如果localeopt = 1,则所有这些参数均采用ODBC默认值。
  • 如果未指定localeopt,则dformat参数确定这些参数的默认值。如果dformat = 3,则使用ODBC默认值。如果dformat为18、19、20或21,则无论当前语言环境定义如何,都使用回教日期和时间格式默认值。对于所有其他dformat值,使用当前的语言环境定义默认值。有关更多详细信息,请参考dformat描述。

不能更改ODBC标准语言环境。它用于格式化日期和时间字符串,这些日期和时间字符串在做出了不同的国家语言支持(NLS)选择的Caché流程之间可移植。 ODBC语言环境日期和时间定义如下:

  • 日期格式默认为3。因此,如果dformat未定义或为-1,则使用日期格式3。
  • 日期分隔符默认为“/”。但是,日期格式默认为3,该格式始终使用“-”作为日期分隔符。
  • Year选项默认为4位数字。
  • 最小和最大日期:0和2980013($HOROLOG日期计数)。
  • 使用英语月份的名称,月份的缩写,工作日的名称,工作日的缩写以及单词“ Noon”和“ Midnight”。
  • 时间格式默认为1。时间分隔符为“:”。时间精度为0(无小数秒)。 AM和PM指示器分别为“ AM”和“ PM”。

示例

以下示例显示当前的本地日期和时间。它采用语言环境的默认日期和时间格式:

DHC-APP>WRITE $ZDATETIME($HOROLOG)
11/12/2020 15:55:07

下面的示例显示当前日期和时间。 $ZTIMESTAMP包含当前日期和时间值,如世界标准时间(UTC)。 dformat参数指定ODBC日期格式,tformat参数指定24小时制,而precision参数指定6位小数秒精度:

DHC-APP>WRITE $ZDATETIME($ZTIMESTAMP,3,1,6)
2020-11-12 07:55:25.407000

这将返回当前时间戳记日期和时间,格式为:2005-11-25 18:45:16.960000。

下面的示例显示了如何将本地时间转换为UTC时间,以及转换后的日期也可能如何更改。在大多数时区中,以下$ZDATETIME操作之一的时间转换也会更改日期:

/// d ##class(PHA.TEST.Function).ZDATETIME2()
ClassMethod ZDATETIME2()
{
    SET local = $ZDATETIME("60219,82824",3,1)
    SET utcwest = $ZDATETIME("60219,82824",3,7)
    SET utceast = $ZDATETIME("60219,00024",3,7)
    WRITE !,local,!,utcwest,!,utceast
}

DHC-APP>d ##class(PHA.TEST.Function).ZDATETIME2()
 
2005-11-15 23:00:24
2005-11-15T15:00:24Z
2005-11-14T16:00:24Z

注意

$ZDATETIME的值无效

在以下情况下,收到 错误:

  • 如果您指定了无效的dformat代码(小于-3或大于17的整数值,零或非整数值)
  • 如果在yearopt为3或5时未指定startwin值。

在以下情况下,会收到错误:

  • 如果为日期或时间指定了一个无效值并且不提供错误值
  • 如果给定的月份数大于monthlist中的月份数。
  • 如果maxdate小于主意。
  • 如果endwin小于startwin。
  • 如果startwin和endwin指定滑动时间窗口,其持续时间大于100年。

在以下情况下,收到错误:

  • 如果指定的有效日期超出了为maxdate和mindate假定的值所定义的范围,并且不提供错误值

可自定义的日期和时间默认值

Caché启动时,默认的日期和时间格式被初始化为美国的日期和时间格式(例如MM / DD / [YY] YY)。要将此格式和其他默认格式设置为当前语言环境的值,请设置以下全局变量:SET ^SYS("NLS","Config","LocaleFormat")=1。这会将所有进程的所有格式默认值设置为当前语言环境值。这些默认值将一直保留到更改此全局变量为止。

注意:本节介绍未定义localeopt或将其设置为0时应用的用户语言环境定义。当localeopt = 1时,$ZDATETIME使用预定义的ODBC语言环境。

在以下示例中,第一个$ZDATETIME以默认格式返回区域设置的日期和时间。输入参数是$ZTIMESTAMP特殊变量,其中dformat和tformat为默认值,精度设置为2个十进制数字。在大多数语言环境中,第一个$ZDATETIME将返回dformat = 1或美国日期和时间格式,并带有斜杠日期分隔符和点小数点分隔符,以秒为单位。

在ChangeVals部分中,第一个SetFormatItem()方法将区域设置日期格式默认更改为dformat = 4或欧洲日期格式(DD / MM / [YY] YY),如第二个$ZDATETIME所示。第二个SetFormatItem()方法更改日期分隔符字符的区域设置默认值(这会影响dformat –1、1、4和15)。在此示例中,日期分隔符字符设置为点(“。”),如第三个$ZDATETIME所示。第三个SetFormatItem()方法将此语言环境的小数点分隔符更改为欧洲标准(“,”),如最后的$ZDATETIME所示。然后,该程序将还原初始日期格式值:

/// d ##class(PHA.TEST.Function).ZDATETIME3()
ClassMethod ZDATETIME3()
{
InitalizeLocaleFormat
    SET ^SYS("NLS","Config","LocaleFormat")=1
InitialVals
    SET fmt=##class(%SYS.NLS.Format).GetFormatItem("DateFormat")
    SET sep=##class(%SYS.NLS.Format).GetFormatItem("DateSeparator")
    SET dml=##class(%SYS.NLS.Format).GetFormatItem("DecimalSeparator")
    WRITE !,$ZDATETIME($ZTIMESTAMP,,,2)
ChangeVals
    SET x=##class(%SYS.NLS.Format).SetFormatItem("DateFormat",4)
    WRITE !,$ZDATETIME($ZTIMESTAMP,,,2)
    SET y=##class(%SYS.NLS.Format).SetFormatItem("DateSeparator",".")
    WRITE !,$ZDATETIME($ZTIMESTAMP,,,2)
    SET z=##class(%SYS.NLS.Format).SetFormatItem("DecimalSeparator",",")
    WRITE !,$ZDATETIME($ZTIMESTAMP,,,2)
RestoreVals
    SET x=##class(%SYS.NLS.Format).SetFormatItem("DateFormat",fmt)
    SET y=##class(%SYS.NLS.Format).SetFormatItem("DateSeparator",sep)
    SET z=##class(%SYS.NLS.Format).SetFormatItem("DecimalSeparator",dml)
    WRITE !,$ZDATETIME($ZTIMESTAMP,,,2)
}

DHC-APP> d ##class(PHA.TEST.Function).ZDATETIME3()
 
11/12/2020 08:01:16.94
12/11/2020 08:01:16.94
12.11.2020 08:01:16.94
12.11.2020 08:01:16,94
11/12/2020 08:01:16.94

ZDATE相比

$ZDATETIME$ZDATE相似,只不过它转换组合的日期和时间值。 $ZDATE仅转换日期值。例如:

DHC-APP>WRITE $ZDATE($HOROLOG)
11/12/2020
DHC-APP> WRITE $ZDATETIME($HOROLOG)
11/12/2020 16:02:11

$ZDATE不支持5到8的tformat值。

你可能感兴趣的:(第八十五章 Caché 函数大全 $ZDATETIME 函数)