🕐
← ガイド一覧に戻る

Unix タイムスタンプのタイムゾーン変換: 実践ガイド

· タグ: timezone, dst, utc, time-conversion, unix-timestamp, daylight-saving, epoch

タイムゾーンが Unix タイムスタンプにとって重要な理由

Unix タイムスタンプ自体はタイムゾーンに依存しません — 数値 1785292800 はどこでも同じ瞬間を意味します。複雑さが生じるのは、その瞬間を表示、ログ記録、またはデータ分析のために人間が読めるローカル時刻に変換するときです。

基本原則: 常に UTC で保存し、表示のためだけに変換する。 このルールはバグのカテゴリ全体を排除し、データをタイムゾーン間で移植可能にします。

UTC とローカル時刻: 違いを理解する

UTC(協定世界時)

UTC は主要な時刻標準です。夏時間のために変わることはなく、地球上のどこでも同じです。Unix タイムスタンプは UTC で定義されています。

ローカル時刻

ローカル時刻は、特定の地理的領域に合わせて調整された UTC です。固定オフセット(中国標準時の UTC+8 など)または可変オフセット(東部時間が DST で UTC-5 と UTC-4 を切り替えるなど)で UTC と異なる場合があります。

オフセットの問題

同じ Unix タイムスタンプでも、観測者の場所によって異なるローカル時刻になります:

| タイムスタンプ | UTC | ニューヨーク (EST) | 東京 (JST) | ロンドン (BST) | |-----------|-----|----------------|-------------|--------------| | 1785292800 | 2026-07-19 00:00 | 2026-07-18 20:00 | 2026-07-19 09:00 | 2026-07-19 01:00 | | 1785379200 | 2026-07-19 23:59 | 2026-07-19 19:59 | 2026-07-20 08:59 | 2026-07-20 00:59 |

夏時間(DST)

DST とは?

夏時間は、夏の間に夜の明るい時間が長く続くように時計を進める慣行です。時計は春に「スプリングフォワード」(1 時間失う)し、秋に「フォールバック」(1 時間得る)します。

タイムスタンプ変換への影響

DST は、ローカル時刻と UTC の間に可変オフセットを生み出します。これは次のことを意味します:

  1. 同じローカル時刻が 2 つの異なるタイムスタンプに対応することがある(「フォールバック」遷移中、午前 1:00 という時刻が 2 回発生します)
  2. 存在しないローカル時刻がある(「スプリングフォワード」遷移中、たとえば午前 2:00 は決して発生しません — 時計は直接午前 3:00 にジャンプします)

例: 曖昧な時刻

アメリカ合衆国の東部時間帯では、11 月の第 1 日曜日の午前 2:00 に、時計は午前 1:00 に戻ります。これは次のことを意味します:

from datetime import datetime, timezone
import pytz

eastern = pytz.timezone("America/New_York")

# First occurrence of 1:00 AM (EDT, UTC-4)
first = eastern.localize(datetime(2026, 11, 1, 1, 0), is_dst=True)
print(first.timestamp())
# Some timestamp value

# Second occurrence of 1:00 AM (EST, UTC-5) = 3600 seconds later!
second = eastern.localize(datetime(2026, 11, 1, 1, 0), is_dst=False)
print(second.timestamp())
# first.timestamp() + 3600

アプリケーションでは、曖昧なフォールバック時刻を常に慎重に扱ってください。Python で is_dst/ambiguous フラグを使用するか、他の言語で同等のオプションを使用すると、微妙なバグを防げます。

タイムゾーン間の変換

当社のオンラインツールを使用する

一度きりの変換に最も簡単なアプローチは、複数のタイムゾーンで結果を同時に表示する当社の Unix タイムスタンプ変換ツール です。

Linux コマンドラインを使用する

# Display timestamp in multiple timezones
TZ="America/New_York" date -d @1785292800
TZ="Europe/London"    date -d @1785292800
TZ="Asia/Tokyo"       date -d @1785292800

# With custom ISO format
TZ="UTC" date -d @1785292800 +"%Y-%m-%d %H:%M:%S %Z"
# Output: 2026-07-19 00:00:00 UTC

TZ="Asia/Shanghai" date -d @1785292800 +"%Y-%m-%d %H:%M:%S %Z"
# Output: 2026-07-19 08:00:00 CST

Python を使用する

from datetime import datetime
from zoneinfo import ZoneInfo  # Python 3.9+

ts = 1785292800

# Convert to multiple timezones
timezones = ["America/New_York", "Europe/London", "Asia/Tokyo", "Australia/Sydney"]

for tz_name in timezones:
    tz = ZoneInfo(tz_name)
    dt = datetime.fromtimestamp(ts, tz=tz)
    print(f"{tz_name}: {dt.strftime('%Y-%m-%d %H:%M:%S %Z')}")

JavaScript を使用する

const ts = 1785292800;
const date = new Date(ts * 1000);

const timezones = [
    "America/New_York",
    "Europe/London",
    "Asia/Tokyo",
    "Australia/Sydney"
];

for (const tz of timezones) {
    const str = date.toLocaleString("en-US", {
        timeZone: tz,
        timeZoneName: "short",
    });
    console.log(`${tz}: ${str}`);
}

Go を使用する

package main

import (
    "fmt"
    "time"
)

func main() {
    t := time.Unix(1785292800, 0)
    
    timezones := []string{
        "America/New_York",
        "Europe/London",
        "Asia/Tokyo",
        "Australia/Sydney",
    }
    
    for _, tz := range timezones {
        loc, _ := time.LoadLocation(tz)
        fmt.Printf("%s: %s\n", tz, t.In(loc).Format("2006-01-02 15:04:05"))
    }
}

一般的なタイムゾーン変換パターン

サーバーログをローカル時刻に変換する

サーバーログは通常、タイムスタンプを UTC で記録します。分析するときは、自分のローカルタイムゾーンに変換します:

# Read a log file and display timestamps in Pacific time
while IFS= read -r line; do
    if [[ $line =~ ^([0-9]+) ]]; then
        ts="${BASH_REMATCH[1]}"
        TZ="America/Los_Angeles" date -d @"$ts" "+%Y-%m-%d %H:%M:%S"
        echo " $line"
    fi
done < server.log

タイムゾーン間でのイベントのスケジューリング

タイムゾーン間でイベント時刻を共有するときは、常に UTC で伝えるか、Unix タイムスタンプを直接共有します。これにより曖昧さがなくなります:

  • 1785292800 に会議」は曖昧さがありません
  • 「午前 9:00 EST に会議」は DST の移行中に曖昧になります
  • 「午前 9:00 America/New_York に会議」はより良いですが、それでも DST の状態を知る必要があります

データベースにタイムスタンプを保存する

-- Always store the timestamp itself (timezone-independent)
INSERT INTO events (occurred_at, user_id) VALUES (1785292800, 42);

-- OR store with an explicit UTC timestamp column
INSERT INTO events (occurred_at_utc, user_id) 
VALUES ('2026-07-19 00:00:00+00', 42);

ベストプラクティスのまとめ

  1. UTC で保存し、表示のために変換する — ローカル時刻をデータベースに保存しないでください
  2. IANA タイムゾーン名を使用する(例: America/New_York)略称(EST、PST)ではなく — 略称は曖昧で、DST を考慮しません
  3. DST を明示的に扱う — タイムゾーン対応ライブラリを使用し、手動で時間を加算/減算しないでください
  4. 常にタイムゾーン情報を渡す — ユーザーから日付を受け取るときは、オフセットだけでなくタイムゾーンも収集してください
  5. 境界の日付をテストする — DST の移行日(春と秋の両方)で変換ロジックをテストして、バグを早期に発見してください

タイムゾーンデータベース

システムのタイムゾーンデータは、IANA タイムゾーンデータベース(オルソンデータベースとも呼ばれます)から取得されます。これは、政府が DST ルールを変更するたびに年に数回更新されます。システムを最新の状態に保ちましょう:

# Debian / Ubuntu
sudo apt update && sudo apt install tzdata

# macOS
# Automatically updated via software updates

# Verify your database version
zdump -v /etc/localtime | head -1

主要なすべてのタイムゾーンにわたるすばやいタイムゾーン対応の変換には、当社の Unix タイムスタンプ変換ツール を使用してください。