サマータイム (DST) とは - 世界各国の対応状況と廃止の動き
サマータイムの仕組み、導入の歴史、各国の現在の対応状況、そして近年の廃止議論について詳しく解説します。
サマータイムの切り替えは年に 2 回、時刻の連続性を破壊します。春の切り替え (例: アメリカ東部で 2:00 AM → 3:00 AM) では 2:00〜2:59 の時刻が存在しなくなります (ギャップ)。秋の切り替え (例: 2:00 AM → 1:00 AM) では 1:00〜1:59 の時刻が 2 回出現します (オーバーラップ)。この 2 つの異常が、ソフトウェアに多様なバグを引き起こします。
ギャップ内の時刻 (例: 2:30 AM EST) をユーザーが入力した場合、システムはどう処理すべきでしょうか。バリデーションエラーとして拒否する、3:30 AM EDT に自動補正する、1:30 AM EST に巻き戻す、いずれの選択も正当化できます。問題は、多くのライブラリがこのケースを暗黙的に処理し、開発者が意図しない動作をすることです。
サマータイムの切り替え日には、「1 日」が 23 時間または 25 時間になります。「現在時刻に 24 時間を加算する」処理と「翌日の同じ時刻を求める」処理は、通常は同じ結果を返しますが、切り替え日には異なります。春の切り替え日に午前 1 時に 24 時間を加算すると翌日の午前 2 時になりますが、「翌日の同じ時刻」は午前 1 時です。
この違いは、定期的なスケジュール (毎日午前 9 時にメール送信) や期限計算 (申込みから 24 時間以内にキャンセル可能) で実害を生みます。「毎日同じ時刻」を意図するなら日付に 1 日を加算し、「正確に 24 時間後」を意図するなら UTC タイムスタンプに 86400 秒を加算すべきです。この 2 つの意図を明確に区別する設計が重要です。
「毎週火曜日の 14:00」という繰り返し予定は、サマータイムの切り替え週にどうなるべきでしょうか。ユーザーの意図は「ローカルタイムの 14:00」であり、UTC の固定時刻ではありません。したがって、繰り返しイベントは「タイムゾーン + ローカルタイム」で保存し、各回の UTC 時刻を動的に計算する設計が正しいです。
RFC 5545 (iCalendar) はこの問題を DTSTART と RRULE の組み合わせで解決しています。DTSTART にタイムゾーン付きのローカルタイムを指定し、RRULE で繰り返しパターンを定義します。各回の実際の UTC 時刻は、そのタイムゾーンのルール (サマータイムを含む) に基づいて計算されます。この設計により、サマータイムの切り替えを跨いでも「ローカルタイムの 14:00」が維持されます。
PostgreSQL の TIMESTAMP (WITHOUT TIME ZONE) は入力された値をそのまま保存し、タイムゾーン変換を行いません。TIMESTAMPTZ (WITH TIME ZONE) は入力を UTC に変換して保存し、取得時にセッションのタイムゾーンに変換して返します。サマータイムの影響を正しく処理するには TIMESTAMPTZ を使用すべきです。
ただし、「ユーザーが入力したローカルタイム」を保持したい場合 (例: 予約時刻) は、TIMESTAMPTZ だけでは不十分です。UTC に変換された時点で「元のタイムゾーン」の情報が失われるためです。この場合は TIMESTAMPTZ に加えてタイムゾーン名を別カラムに保存し、表示時に元のタイムゾーンで復元する設計が必要です。
サマータイム関連のバグは年に 2 回しか発現しないため、通常のテストでは検出困難です。テストコードでは、切り替え前後の時刻を明示的にテストケースに含める必要があります。具体的には、ギャップ内の時刻の入力、オーバーラップ時の曖昧な時刻の解決、切り替え日をまたぐ期間計算、切り替え日の繰り返しイベント生成をカバーします。
テスト環境のタイムゾーンを固定することも重要です。開発者のローカル環境が UTC+9 (サマータイムなし) で、本番環境が America/New_York (サマータイムあり) の場合、ローカルでは通るテストが本番で失敗します。テスト対象の関数にタイムゾーンを引数として渡す設計にするか、テスト実行時に TZ 環境変数を明示的に設定することで、環境依存を排除できます。
この記事は役に立ちましたか?
サマータイムの仕組み、導入の歴史、各国の現在の対応状況、そして近年の廃止議論について詳しく解説します。
2 つの都市間の時差を正確に計算する方法を、UTC オフセットの基本から、サマータイムを考慮した実践的な変換手順まで段階的に解説します。
ソフトウェア開発における UTC 変換の正しい実装方法を解説。保存は UTC、表示はローカルの原則から、JavaScript/Python での具体的な実装パターン、よくあるバグの原因まで網羅します。