第四十五章 Caché 函数大全 $NOW 函数 第四十五章 Caché 函数大全 $NOW 函数 大纲 描述 示例

第四十五章 Caché 函数大全 $NOW 函数

返回当前日期的本地日期和时间,以小数秒为单位。

大纲

$NOW(tzmins)

参数

  • tzmins
    • 可选—正整数或负整数,以分钟为单位指定距格林威治子午线的期望时区偏移量。值0对应于格林威治子午线。正整数对应于格林威治以西的时区;负整数对应于格林威治东部的时区。例如,值300对应于格林威治以西5小时(300分钟)的美国东部标准时间。允许值的范围是-1440至1440;值超出此范围会导致错误。
    • 如果省略tzmins,则$NOW函数将根据$ZTIMEZONE特殊变量值返回本地日期和时间。 $NOW函数支持的$ZTIMEZONE值的范围是-1440至1440;值超出此范围会导致错误。

描述

$NOW可以返回以下内容:

  • 当前本地日期和时间,以秒为单位表示当前进程。
  • 当前进程在指定时区的本地日期和时间,以小数秒为单位。

$NOW函数返回一个字符串,该字符串由两个数值组成,以逗号分隔。第一个数字是代表当前本地日期的整数。第二个是代表当前本地时间的小数。这些值是计数器,而不是用户可读的日期和时间。

$NOW以Caché存储($HOROLOG)格式返回日期和时间,并带有小数秒的附加功能。 $NOW以以下格式返回当前本地日期和时间:ddddd,sssss.ffffff

第一个整数(ddddd)是自1840年12月31日以来的天数,其中第1天是1841年1月1日。此日期整数的最大值是2980013,对应于9999年12月31日。

第二个数字(ssssss.ffffff)是自当天午夜以来的秒数(以及小数秒)。 Caché将sssss字段从0递增到86399秒。当它在午夜达到86399时,Caché将sssss字段重置为0,并将日期字段递增1。注意,在午夜之后的第一秒内,秒表示为0.ffffff(例如0.123);此数字不是ObjectScript规范形式(例如.123),这会影响这些值的字符串排序顺序。可以在执行排序操作之前在加号(+)之前强制将数字转换为规范形式。ffffff小数位数是当前操作系统支持的最大精度。

$NOW函数可以在有或没有参数值的情况下调用。括号是必需的。

没有参数值的$NOW返回当前进程的当前本地日期和时间。它根据$ZTIMEZONE特殊变量中设置的值确定本地时区。设置$ZTIMEZONE会更改$NOW的时间部分,并且此时间更改也会更改$NOW的日期部分。

注意

$NOW当地时间值可能与本地时钟时间不对应。 $NOW使用$ZTIMEZONE值确定本地时间。 $ZTIMEZONE全年持续;它不会针对夏令时(DST)或其他当地时间变化进行调整。

使用格林威治子午线的时区计数来计算UTC时间的偏移量。它不是你本地时间与本地格林威治时间的比较。格林威治标准时间(GMT)一词可能令人困惑;格林威治的当地时间与冬季的UTC相同。在夏季,它与UTC相差一小时。这是因为应用了称为英国夏令时的本地时差。 $NOW忽略所有本地时变。

同样,由于$NOW将其时间值与系统时钟重新同步,因此$NOW与其他Caché时间函数和特殊变量之间的时间值比较可能会显示出细微的差异。此变化限制为0.05秒;但是,在此变化范围内,比较可能会产生误导性的结果。例如,WRITE $NOW(),!,$HOROLOG可能会产生如下结果:

61438,38794.002085
61438,38793

此异常是由0.05秒的重新同步变化和分数秒的$HOROLOG截断引起的。

带有参数值的$NOW返回与以tzmins为单位的时区相对应的时间和日期。 $ZTIMEZONE的值将被忽略。

时间函数比较

比较了返回当前日期和时间的各种方法,如下所示:

  • $NOW返回当前进程的本地日期和时间。 $NOW以Caché存储格式返回日期和时间。它包括小数秒;小数位数是当前操作系统支持的最大精度。
    • $NOW()根据$ZTIMEZONE特殊变量的值确定本地时区。本地时间未针对本地时间变量进行调整,例如夏令时。因此,它可能与本地时钟时间不对应。
    • $NOW(tzmins)返回与指定的tzmins时区参数相对应的时间和日期。 $ZTIMEZONE的值将被忽略。
  • $HOROLOG以Caché存储格式包含经过变量调整的本地日期和时间。本地时区由$ZTIMEZONE特殊变量的当前值确定,然后针对本地时间变量(例如,夏令时)进行调整。它只返回整秒。小数秒被截断。
  • $ZTIMESTAMP以Caché存储格式包含UTC(世界标准时间)日期和时间(以小数秒为单位)。小数秒以三位精度(在Windows系统上)或六位精度(在UNIX®系统上)表示。因此,$NOW(0)返回的UTC时间的秒精度要比$ZTIMESTAMP高。

这些返回当前日期和时间的方法都不能完全替代过时的$ZUTIL(188)函数,该函数提供了本地日期和时间以及本地时间变体和小数秒的调整。

DHC-APP>w $zutil("188")
65644,81627.106176
DHC-APP>w $now()
65644,81630.608212
DHC-APP>W $H
65644,81633

Windows上的微秒

Windows系统上的微秒精度通常比其他平台的精度低。这是由于QueryPerformanceCounter()Windows库例程的限制。 Caché通过将QueryPerformanceCounter()计算的结果与用于其他日期/时间函数的系统时钟进行比较来确定微秒,该时钟的精度最高为1毫秒(根据运行Windows的硬件,精度通常在1到20毫秒之间)。 $NOW微秒精度时钟与毫秒级精度时钟相差超过50毫秒,Caché向前或向后调整微秒级精度时钟,以与精度更高(但精度较低)的毫秒级时钟一致。

因此,在Windows上,$NOW函数(和传统的$ZUTIL(188)函数)仅适用于在很短的持续时间内(不超过几秒钟)测量微秒精度的时间间隔。在具有多个CPU内核的系统上,每个内核的CachéWindows进程将进行微秒调整,该调整仅针对单个进程。这意味着在不同的CachéCPU进程上返回的$NOW值可能彼此不一致。当Windows在多核CPU芯片上托管的虚拟机上运行时,CPU进程之间的差异更加明显。

分隔日期和时间

要仅获取$NOW的日期部分或时间部分,可以使用$PIECE函数,将逗号指定为定界符:

/// d ##class(PHA.TEST.Function).NOW()
ClassMethod NOW()
{
    SET dateval=$PIECE($NOW(),",",1)
    SET timeval=$PIECE($NOW(),",",2)
    WRITE !,"Date and time: ",$NOW()
    WRITE !,"Date only: ",dateval
    WRITE !,"Time only: ",timeval
}
DHC-APP>d ##class(PHA.TEST.Function).NOW()
 
Date and time: 65644,81724.239158
Date only: 65644
Time only: 81724.239154

设定日期

$NOW$ZTIMESTAMP返回的值不能使用%SYSTEM.Process类的FixedDate()方法设置。

可以使用%SYSTEM.Process类的FixedDate()方法将$HOROLOG中包含的值设置为当前过程的用户指定日期。

示例

以下示例显示了两种返回当前本地日期和时间的方法:

DHC-APP> WRITE $ZDATETIME($NOW(),1,1,3)," $NOW() date & time",!
09/22/2020 22:43:22.565 $NOW() date & time
 
DHC-APP>WRITE $ZDATETIME($HOROLOG,1,1,3)," $HOROLOG date & time"
09/22/2020 22:43:28.000 $HOROLOG date & time
DHC-APP>WRITE $ZDATETIME($HOROLOG,3,1,6)
2020-09-22 22:44:47.000000
DHC-APP>WRITE $ZDATETIME($now(),3,1,6)
2020-09-22 22:44:58.894816

请注意,$HOROLOG会针对本地时间变量进行调整,例如夏令时。 $NOW不会针对当地时间变化进行调整。

下面的示例使用$ZDATE$NOW中的日期字段转换为日期格式。

DHC-APP> WRITE $ZDATE($PIECE($NOW(),",",1))
09/22/2020

下面的示例将$NOW的时间部分转换为12小时(上午或下午)时钟的小时:分钟:秒.ffff形式的时间。

/// d ##class(PHA.TEST.Function).NOW1()
ClassMethod NOW1()
{
   
    NEW
    SET Time = $PIECE($NOW(),",",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
}
DHC-APP>d ##class(PHA.TEST.Function).NOW1()
 
10:48:38.77612 pm
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章