日付からEpochへの変換
人間が読める日付をUnix epoch timestampに変換する方法を複数言語で解説。タイムゾーンの考慮事項やよくあるパースミスについても説明します。
Conversion
2024-01-01 → 1704067200
詳細な説明
人間が読める日付をUnix epoch timestampに変換するのは、epochから日付への変換の逆ですが、入力日付がどのタイムゾーンにあるかを変換前に決定する必要があるため、追加の複雑さを伴います。
タイムゾーンの問題: 文字列「2024-01-01 00:00:00」はタイムゾーンなしでは曖昧です。UTCの午前0時なのか、ニューヨークなのか、東京なのか。解釈によって異なるUnix timestampが生成されます:
2024-01-01 00:00:00 UTC → 1704067200
2024-01-01 00:00:00 US/Eastern → 1704085200 (+5時間)
2024-01-01 00:00:00 Asia/Tokyo → 1704034800 (-9時間)
主要言語での変換例:
// JavaScript
new Date("2024-01-01T00:00:00Z").getTime() / 1000
// 1704067200
// 'Z'なしだとブラウザによって挙動が異なる!常にタイムゾーンを含めること。
# Python
from datetime import datetime, timezone
dt = datetime(2024, 1, 1, tzinfo=timezone.utc)
int(dt.timestamp())
# 1704067200
# 文字列のパース
from datetime import datetime
dt = datetime.strptime("2024-01-01", "%Y-%m-%d")
# 警告:これはnaive(タイムゾーンなし)— .timestamp()はローカル時刻を仮定
// Java
LocalDate.parse("2024-01-01")
.atStartOfDay(ZoneOffset.UTC)
.toEpochSecond()
// 1704067200
-- MySQL
SELECT UNIX_TIMESTAMP('2024-01-01 00:00:00');
-- PostgreSQL
SELECT EXTRACT(EPOCH FROM '2024-01-01 00:00:00 UTC'::timestamptz);
よくある落とし穴:
Pythonでは、naiveなdatetime(タイムゾーン情報なし)に対して.timestamp()を呼び出すとローカル時刻を仮定するため、コードを実行するマシンによって異なる結果になります。変換前に必ずdatetimeにタイムゾーンを付与してください。
JavaScriptでは、"2024-01-01"のような日付のみの文字列はUTCとしてパースされますが、"2024-01-01T00:00:00"のような日時文字列(Zやオフセットなし)はローカル時刻としてパースされます。ECMAScript仕様におけるこの不整合は、長年にわたる混乱の原因です。
バリデーション: ユーザー入力を変換する前に日付を検証してください。2月30日や13月のような無効な日付は、一部の言語ではエラーではなく予期しない結果を生成する場合があります。利用可能な場合はstrict parsingモードを使用しましょう。
ユースケース
日付範囲フィルター付きのレポートダッシュボードを構築する際、ユーザーが選択した日付をそのユーザーのタイムゾーンでepoch timestampに変換して、データベースを正確にクエリする必要があります。