Linux

為什麼指定日期時,GNU 日期的“-”(減號)解釋與直覺的解釋不同?

  • April 19, 2021

如果我從目前日期中減去時間量,GNU 日期可以直覺地工作:

date '+%F %R'; date '+%F %R' --date='- 1 hour'
2021-04-19 15:35
2021-04-19 14:35

但是,當我使用日期作為操作數時,結果出乎意料:

$ date '+%F %R' --date='2000/1/2 03:04:05 - 1 hour'
2000-01-02 06:04

$ date '+%F %R' --date='2000/1/2 03:04:05 + 1 hour ago'
2000-01-02 02:04

如何date解釋$date - 1 hour表達式?

簡而言之:您給出的日期--date是當地時間,除非您指定時區,並且類似的東西+/- NNN被視為一個。只有在那之後的任何東西,即使它只是hour被視為相對修飾符。所以- 1 hour並不意味著從給定時間中減去一小時,而是指定時間在 UTC-01 時區,然後再增加一小時。


我認為應該適用於您正在嘗試的內容,是在偏移量之前明確給出時區,或者將偏移量放在首位,這樣它就不會與時區混淆。

在這裡,使用中歐夏令時時區 (CEST) 和今天的日期,%Z添加到輸出以顯示時區。(您也可以%z用來輸出數字時區,或者+0200在這裡。)

$ date +'%F %T %Z' -d '2021-04-19 12:00:00 CEST + 5 hours'
2021-04-19 17:00:00 CEST
$ date +'%F %T %Z' -d '+ 5 hours 2021-04-19 12:00:00'
2021-04-19 17:00:00 CEST

當然,對於像問題中這樣的一月日期,像 CEST 這樣的夏季時區將不是一個有效的時區。但是重新排列兩者仍然有效,您給出的時間只是作為當時的當地時間。

$ date +'%F %T %Z' -d '+ 5 hours 2021-01-01 12:00:00'
2021-01-01 17:00:00 CET

(而且因為2021-10-31 02:30:00我得到了 CET,即使那個時間也存在於 CEST 中……)

(有關它如何解釋各種輸入的更多範例,請參閱此答案的舊版本。)


根據@muru 對另一個問題的回答,我們還可以使用該--debug選項讓程序實際告訴我們它做了什麼。注意第二行和第三行:

$ date --debug +'%F %T %Z' -d '2021-04-19 12:00:00 - 1 小時'
日期:解析日期部分:(YMD)2021-04-19
日期:**解析的時間部分:12:00:00 TZ=-01:00**
日期:**解析的相對部分:+1 小時**
日期:輸入時區:-01:00(從解析的日期/時間字元串設置)
日期:使用指定時間作為起始值:'12:00:00'
日期:開始日期/時間:'(YMD) 2021-04-19 12:00:00 TZ=-01:00'
日期:'(YMD)2021-04-19 12:00:00 TZ=-01:00' = 1618837200 紀元秒
日期:時間調整後(+1 小時,+0 分鐘,+0 秒,+0 ns),
日期:新時間 = 1618840800 紀元秒
日期:輸出時區:+01:00(從 TZ="Europe/Berlin" 環境值設置)
日期:最終:1618840800.000000000(紀元秒)
日期:最終:(YMD)2021-04-19 14:00:00(UTC0)
日期:最終:(YMD)2021-04-19 16:00:00(輸出時區 TZ=+01:00)
2021-04-19 16:00:00 CEST

手冊頁說:

日期字元串格式比這裡容易記錄的更複雜

$$ … $$

這確實看起來很恰當。更全面的文件在資訊頁面或線上:https ://www.gnu.org/software/coreutils/manual/html_node/Date-input-formats.html

引用自:https://unix.stackexchange.com/questions/645758