タイムゾーンとDSTの罠|日付がズレる本当の原因
国際展開で日付がズレる典型パターン
「日本では正しく動くのに、海外ユーザだけ予約日付が1日ズレる」「米国の夏時間切り替え時刻にcron jobが2回実行される」。これらの大半はタイムゾーンとDST(夏時間)の理解不足が原因です。
UnixTime Converter を使いながら、起きやすい問題を整理します。
「同じ時刻」だけど「同じUnixTime」じゃない
JST 12:00 と UTC 12:00
Asia/Tokyo 2026-05-10 12:00:00 → UnixTime 1747821600
UTC 2026-05-10 12:00:00 → UnixTime 1747854000
32400秒(=9時間)の差。日本のサーバ側で「2026-05-10 12:00:00」と書いたつもりが、UTC基準で解釈されると、ユーザには「3:00 AM」として表示される、というズレが起きます。
→ UnixTime Converter で同じ日付文字列を入力し、タイムゾーンだけ切り替えるとUnixTime値が変わるのが確認できます。
「2026-05-10」だけ書くとどう解釈されるか
ISO 8601 + タイムゾーン指定(明示)
2026-05-10T12:00:00+09:00 ← JST明示
2026-05-10T12:00:00Z ← UTC明示(Z=Zulu time)
これが最も安全。本ツールは末尾の Z や +09:00 を検出してそれで解釈します。
タイムゾーン指定なし
2026-05-10 12:00:00
このときの解釈はライブラリ・言語・設定によって異なります:
| 環境 | 解釈 |
|---|---|
JavaScript new Date("2026-05-10 12:00:00") | ローカルTZ |
JavaScript new Date("2026-05-10T12:00:00") | ローカルTZ |
JavaScript new Date("2026-05-10") | UTC(仕様で決まっている) |
MySQL TIMESTAMP | サーバTZ |
MySQL DATETIME | TZ情報なし、入れたまま |
PostgreSQL TIMESTAMPTZ | UTC変換して保存 |
「ローカルTZ」と書いてあるものは、サーバとブラウザで違う結果になります。本ツールは「選択中のタイムゾーンの壁時計」として明示的に解釈します。
DST(夏時間/Daylight Saving Time)
日本にはないが世界にはある
| 国・地域 | DST | 切替時期 |
|---|---|---|
| 日本 | なし | — |
| 米国・カナダ | あり | 3月第2日曜 / 11月第1日曜 |
| EU諸国 | あり | 3月最終日曜 / 10月最終日曜 |
| 中国・シンガポール | なし | — |
| オーストラリア | 一部のみ | 10月第1日曜 / 4月第1日曜 |
DSTがあるTZでは、1年に2回、UTCとのオフセットが変わります。
春の「存在しない時刻」
米国 America/New_York の例:
2026-03-08 01:59:59 EST (UTC-5)
2026-03-08 03:00:00 EDT (UTC-4) ← 02:00〜02:59 が存在しない
つまり「2026-03-08 02:30:00 America/New_York」は仕様上ありえない時刻。本ツールでは:
DST境界の可能性: 入力した時刻がこのタイムゾーンに存在しないか、重複しているため、近い時刻で解釈しました。
という警告が出ます。
秋の「重複する時刻」
2026-11-01 01:59:59 EDT (UTC-4)
2026-11-01 01:00:00 EST (UTC-5) ← 01:00〜01:59 が2回ある
「2026-11-01 01:30 America/New_York」は1時半が2回あるため、どちらの瞬間かが曖昧。本ツールでは早い方(EDT側)として解釈する実装が多いですが、警告を出します。
DSTで起きるバグの典型
1. cronが2回実行される
サーバTZが米国DST切替日の
01:30を秋に通過 → 同じ時刻が2回 → 2回実行
→ サーバTZをUTCに固定するのが定石。
2. 予約システムで「予約できない」エラー
ユーザが「明日の朝6時」と書く → クライアントローカルTZで解釈 → DST境界の存在しない時刻にマッチ → 保存失敗
→ 入力時にDST境界をチェックして警告。
3. 期間集計が間違う
1日を「86400秒」と決め打ち → DST切替日は86400秒ではない(春は82800秒、秋は90000秒)
→ DBの日付関数を使う、UTCで集計する。
国際対応の鉄則
| 場面 | 推奨 |
|---|---|
| サーバTZ | UTC固定 |
| DBストレージ | UTC(or TIMESTAMPTZ) |
| ログ | UTC(同期しやすい) |
| ユーザ表示 | クライアントTZに変換 |
| 入力フォーム | TZ明示(タイムゾーン選択UI) |
| DST境界の入力 | エラーまたは警告 |
「保存はUTC、表示は現地TZ」がほぼ全てのケースで正解です。
関連記事
時刻のバグの大半は「TZ・DSTの認識ズレ」が原因。UTCで保存し、表示時に変換、という方針を貫けば多くは防げます。