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