第四十五章 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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章