日期和時區偏移無法正常工作
在 Solaris 上使用時區偏移時,我遇到了 date 命令的奇怪行為。
>echo $TZ MET >date Wed Mar 31 11:41:45 MEST 2021 >TZ=MET+24 date Tue Mar 30 09:42:06 MET 2021 >TZ=MEST+24 date Tue Mar 30 09:42:52 MEST 2021
為什麼當 TZ 設置為 MET 時日期輸出顯示 MEST,以及 TZ+24 如何在兩個時區顯示 26 小時偏移而不是 24。
因此,您希望了解為什麼會發生這種情況(簡化):
$ TZ=MET date; TZ=MET+0 date Tue 01 Jun 2021 06:00:00 AM MEST Tue 01 Jun 2021 04:00:00 AM MET
MET
即:和之間有兩個小時的差異MET+0
。調試此問題的最簡單方法是添加
'+%z'
格式。這將列印日期用於列印結果的偏移量,並有助於調試問題出在哪裡。$ TZ=MET date "+%c %z"; TZ=MET+0 date "+%c %z" Wed 31 Mar 2021 06:11:16 PM MEST +0200 Wed 31 Mar 2021 04:11:16 PM MET +0000
這表明日期正在以
-2
偏移量和+0
偏移量列印結果。那麼問題來了:為什麼?
可能是因為 TZ 的第一種格式是
std offset
(類似於 TAG-03 POSIX 參考),其中定義了標準區域的TAG,並給出了該標籤的可選偏移量。如果缺失,則假定偏移量為+0
。因此,我們將 MET 設置
name
為 MET,將偏移量設置為 +0。證明:
$ TZ=MET date "+%c %z"; TZ=METX+7:30 date "+%c %z" Wed 31 Mar 2021 06:19:00 PM MEST +0200 Wed 31 Mar 2021 08:49:00 AM METX -0730
TAG很簡單:它是為時區列印的名稱。
用於此類標籤的偏移量是給定的:(
-7:30
不問任何問題)。您應該清楚,在
METX
任何地方都沒有這樣的標籤,而且在那個標籤上也沒有 7:30 這樣的偏移量。這就解釋了為什麼
MET+24
列印帶有標籤的區域時間MET
和昨天的偏移量+0
(相當於,如果您願意+24
,請嘗試)。+12
正確的 TZ
我們可以測試一個說標準時間是 7 小時而夏令時是 9 小時的 TZ:MET-7MEST-9。為了測試,我們需要 faketime(需要為 Solaris 編譯),它會列印:
$ # In January (no DST): $ faketime "1/1/21 12:00" bash -c 'date -u; TZ=MET date "+%c %z"'; \ faketime "1/1/21 12:00" bash -c 'TZ=MET-7MEST-9 date "+%c %z"' Fri 01 Jan 2021 04:00:00 PM UTC Fri 01 Jan 2021 05:00:00 PM MET +0100 Fri 01 Jan 2021 11:00:00 PM MET +0700 $ # In June (DST in effect) $ faketime "6/1/21 12:00" bash -c 'date -u; TZ=MET date "+%c %z"'; \ faketime "6/1/21 12:00" bash -c 'TZ=MET-7MEST-9 date "+%c %z"' Tue 01 Jun 2021 04:00:00 PM UTC Tue 01 Jun 2021 06:00:00 PM MEST +0200 Wed 02 Jun 2021 01:00:00 AM MEST +0900
這只是為了證實我們的分析。TZ 值可以減少到MET-7MEST,因為 DST 的預設效果是增加 1 小時的時間。而且,由於 MET 的實際 UTC 偏移量是 +1,我們可以說 TZ 應該是:MET-1MEST。如果缺少 dst 標記 (
MET-1
),則不應用 dst 偏移量。對於將時間設置為昨天(+24 小時)的目標,您應該使用:
TZ='MET+23MEST'
問題?