欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-07-01 10:41:53
...

文章目录

第四十五章 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