hwclock 的輸出在進入時受 DST 影響,但在離開時不受
我將系統時間和 RTC 設置為以下值。
date -s 2021.08.30-09:59:30 >/dev/null 2>/dev/null //set system time hwclock -w //sync RTC to system time
此外,/etc/TZ(與 /etc/localtime 中的文件相同
busybox
)另存為LMT0:00LMT-1:00,M5.5.1/10,M8.5.1/10
這意味著 DST 將於 5 月上週的星期一上午 10:00 生效;並將於 8 月上週的星期一上午 10:00 停用。
我特意將系統時間和 RTC 設置為比夏令時結束日期早 30 秒,以觀察系統行為。
當 DST 消失時,系統時間(也可能是 RTC?)應該減去一小時。
以下是結果,很明顯只減去了系統時間一小時,而不是系統時間和 RTC。
~ # cat /etc/TZ LMT0:00LMT-1:00,M5.5.1/10,M8.5.1/10 ~ # date -s 2021.08.30-09:59:30 >/dev/null 2>/dev/null ~ # hwclock -w ~ # ~ # date Mon Aug 30 09:59:36 LMT 2021 ~ # hwclock Mon Aug 30 09:59:42 2021 0.000000 seconds ~ # ~ # ~ # date Mon Aug 30 09:59:49 LMT 2021 ~ # hwclock Mon Aug 30 09:59:53 2021 0.000000 seconds ~ # date Mon Aug 30 09:00:00 LMT 2021 ~ # hwclock Mon Aug 30 10:00:03 2021 0.000000 seconds ~ # date Mon Aug 30 09:00:05 LMT 2021 ~ # hwclock Mon Aug 30 10:00:06 2021 0.000000 seconds
但是,另一方面,它的行為不同!這次我想觀察進入夏令時時的系統行為。
隨著 /etc/TZ 被保存為
LMT0:00LMT-1:00,M8.5.1/10,M12.5.1/10
這意味著 DST 將於 8 月的上周星期一上午 10:00 生效;並將於 12 月上週的星期一上午 10:00 停用。
此外,我將系統時間和 RTC 設置為以下值。
date -s 2021.08.30-09:59:30 >/dev/null 2>/dev/null //set system time hwclock -w //sync RTC to system time
當 DST 生效時,系統時間(也可能是 RTC?)應該提前一小時添加。
結果如下,很明顯係統時間和RTC都加了一小時。
~ # cat /etc/TZ LMT0:00LMT-1:00,M8.5.1/10,M12.5.1/10 ~ # date -s 2021.08.30-09:59:30 >/dev/null 2>/dev/null ~ # hwclock -w ~ # ~ # date Mon Aug 30 09:59:35 LMT 2021 ~ # hwclock Mon Aug 30 09:59:37 2021 0.000000 seconds ~ # date Mon Aug 30 09:59:48 LMT 2021 ~ # hwclock Mon Aug 30 09:59:51 2021 0.000000 seconds ~ # date Mon Aug 30 11:00:04 LMT 2021 ~ # hwclock Mon Aug 30 11:00:06 2021 0.000000 seconds
我想知道為什麼會出現這種矛盾的行為。
您正在考慮
hwclock
顯示硬體時鐘在其寄存器中的確切值。它不這樣做。
證明:
# date; hwclock; TZ=UTC hwclock; grep rtc_time /proc/driver/rtc Wed 1 Sep 18:33:18 EEST 2021 2021-09-01 18:33:18.870798+03:00 2021-09-01 15:33:18.981738+00:00 rtc_time : 15:33:20
注意
hwclock
和的輸出TZ=UTC hwclock
有何不同?
hwclock
根據需要顯示轉換為目前時區的硬體時鐘值*(包括 DST 偏移量和時區)*。如果您想查看原始值,您cat /proc/driver/rtc
必須time_t
使用time64_t
) 並返回時鐘設置過程。在獲取/設置硬體時鐘時也不要使用
--utc
nor--local
選項,因此硬體時鐘的本地/UTC 狀態由/etc/adjtime
文件的第三行(如果存在)確定。在您的第一個測試中,您在 DST 生效時設置硬體時鐘,因此 UTC 偏移量為 -1(UTC=local - 1 小時)。如果硬體時鐘設置為使用本地時間,它將按預期設置為 09:59:30。
但如果硬體時鐘設置為使用 UTC,則設置到時鐘寄存器的實際值將是08:59:30。當您在 DST 轉換之前查看時鐘時,此偏移量會自動取回
hwclock
,因此您將看到 09:59:** 與預期一樣。當 DST 轉換發生時,如果硬體時鐘設置為本地時間,時鐘寄存器將遞增到 10:00:00 的值。由於它已經是當地時間並且 DST 偏移量現在為 0,
hwclock
因此將其顯示為 10:00:00。但如果硬體時鐘設置為 UTC 時間,時鐘寄存器中的值現在將是 09:00:00。由於在 DST 轉換之後,UTC 偏移量現在為 0,
hwclock
因此也會將其顯示為 09:00:00。作業系統時鐘始終在 UTC 內部執行,並根據時區+DST 規則轉換為本地時間,因此它將按預期顯示 09:00:00(非 DST)。
由於您在
hwclock
這裡得到了 10:00:00 的結果,因此文件的第三行似乎/etc/adjtime
必須說LOCAL
.在您的第二個測試中,您在 DST 無效時設置了時鐘,因此總 UTC 偏移量為 0。現在,無論設置為使用 UTC 還是本地時間,時鐘寄存器都將設置為 09:59:30 . 從之前的測試中,我們知道您已將其設置為當地時間。
當 DST 轉換時間到達時,硬體時鐘寄存器將讀取 10:00:00… 並且由於寄存器值根據目前時區格式化顯示,因此存在問題:根據有效的時區規則,10 :00:00 當地時間今天不存在!
由於 DST 轉換,沒有可能的 UTC 時間戳值可以表示這個特殊日子的本地時間 10:00:00 的值:09:59:59 UTC 是本地時間 09:59:59,但是 10:00 :00 UTC 是當地時間 11:00:00。隨著時間值通過
glibc
的時區轉換和格式化常式,不存在的 10:00:00 被推到 11:00:00。因此,如果您在 DST 到標準時間轉換後的第一個小時內查詢硬體時鐘,
hwclock
可能會告訴您不正確的時間,因為時鐘寄存器中的實際值不能表示為有效的本地時間值。這只是一個顯示工件:/proc/driver/rtc
即使在這個神奇的時刻也應該顯示正確的值。這是一個很好的例子,說明了將硬體時鐘設置為本地時間可能會導致的各種令人頭疼的問題。
最後,我將附上 Tom Scott 關於電腦計時的非常適用的 10 分鐘 YouTube 影片的連結。我相信你會欣賞這個結論。