夏時間(DST)とTimestamp

夏時間がtimestampとソフトウェアに与える影響を解説。厄介なエッジケース、曖昧な時刻、DST対応のベストプラクティスを詳しく説明します。

Concept

DST transition

詳細な説明

夏時間(Daylight Saving Time / DST)は、日照時間の長い月に時計を1時間進める慣行です。開発者にとってDSTは、壁掛け時計の時刻とUTCの関係を一年を通じて不安定にするため、ソフトウェアにおける最も微妙で厄介なバグを引き起こします。

2つの危険な移行:

春の前進(Spring forward): 時計が午前2:00から午前3:00に飛ぶとき、2:00〜2:59の間の時刻は存在しません。システムが春の前進の日に午前2:30のタスクをスケジュールしていると、スキップされるか、シフトする必要があります。

秋の後退(Fall back): 時計が午前2:00から午前1:00に戻るとき、1:00〜1:59の間の時刻が2回発生します。「午前1:30」というtimestampは曖昧で、1回目か2回目のどちらかを指す可能性があります。

春の前進 (米国、3月第2日曜日):
1:59 AM EST → 3:00 AM EDT    (2:00-2:59は存在しない)

秋の後退 (米国、11月第1日曜日):
1:59 AM EDT → 1:00 AM EST    (1:00-1:59が2回発生する)

なぜUnix timestampはDSTの影響を受けないか: Unix timestampはUTCでepochからの秒数を、DSTを一切考慮せずに数えます。値は単調に増加します。DSTが影響するのは、Unix timestampとローカル壁掛け時計時刻の間の変換だけです。timestampを常にUTCまたはUnix epoch値で保存すべきもう一つの理由です。

実用上の落とし穴:

  • 日付を引き算して「1日」を得ても、常に86,400秒とは限りません。DSTの移行日には1日が23時間または25時間になる場合があります。
  • 午前2:00〜2:59にスケジュールされたcronジョブは、秋の後退日に2回実行されるか、春の前進日にまったく実行されない可能性があります。
  • DSTの境界をまたぐローカル時刻での期間計算は誤った結果を生みます。

ベストプラクティス:

日付演算は常にUTCで行い、表示時にのみローカル時刻に変換してください。オフセットをハードコードするのではなく、IANAタイムゾーンルール(tzdataまたはOlsonデータベース)を使用してください。タイムゾーンデータベースは最新に保ちましょう。政府はDSTルールを頻繁に変更します(ヨルダンやチリが最近行ったように、予告がほとんどない場合もあります)。

ユースケース

オンコールローテーションシステムはDSTを正しく処理する必要があります。秋の後退の夜に午前1時から午前5時までのシフトが4時間ではなく5時間続くべきで、そうでないとオンコールカバレッジに空白が生じます。

Try It — Timestamp Converter

フルツールを開く