Unix タイムスタンプ変換

Unix タイムスタンプを任意のタイムゾーンの日時に、また日時をエポック値に変換します。

現在の Unix 時刻
判別中…
入力

Unix タイムスタンプとは何か

Unix タイムスタンプ — エポック時刻、あるいは POSIX 時刻とも呼ばれます — は、1970 年 1 月 1 日 00:00:00 UTC (Unix エポックと呼ばれる瞬間) から何秒が経過したかを数える単一の数値です。タイムゾーンも暦も書式もない一つの整数であるため、時間のある瞬間を保存・整列・比較したり、ネットワーク越しに送ったりする必要があるとき、コンピューターが手を伸ばす形式です。データベースの「created_at」列、JWT の「iat」「exp」クレーム、ファイルの mtime、そしてこれから読むほぼすべてのログファイルのタイムスタンプの背後にあるのがこれです。

引き換えになるのは、素の数値は人には何も意味しないことです。1716197600 は申し分なく正しい瞬間ですが、それが先週の火曜なのか 3 年前なのかはひと目では分かりません。その両方向の翻訳こそ、このツールが行うことです。

秒かミリ秒か — 人を噛む曖昧さ

元来の Unix の慣習は整数の秒を数え、シェルの date +%s、PHP の time()、切り捨てた Python の time.time() から得られるのがこれです。JavaScript、Java などの多くはミリ秒を数えます: Date.now() は 1000 倍大きな数を返します。どちらも「タイムスタンプ」と呼ばれ、取り違えることは最もよくある日付バグの一つです。

その失敗は大声ではなく静かに起きます。ミリ秒の値を秒として読めば日付は数万年先に飛び、秒の値をミリ秒として読めばすべてが 1970 年 1 月に潰れます。どちらもエラーを投げません — 本物に見える誤った日付が得られるだけです。

このツールは数の大きさから推測し、その推測を結果のすぐ横に伝えます。今日のエポック秒は 10 桁、今日のエポックミリ秒は 13 桁なので、推測はほぼ常に正しいのですが、これからバグ報告に貼り付けようとする値に「ほぼ」では足りません。だから解釈は常に見えていて、常にワンクリックで切り替えられます。

タイムゾーン、UTC、そして「ローカル」が曖昧な理由

Unix タイムスタンプにはタイムゾーンがありません。それは一つの瞬間を指し、その同じ瞬間はロンドンでは 09:33、エルサレムでは 11:33、東京では 18:33 に同時になります。タイムゾーンは値の一部ではなく、値を通して見るレンズです。

だからこのツールは複数のレンズを一度に表示します。UTC はすべてのサーバーとログが一致する中立の基準です。ローカル時刻はお使いの端末が報告するもので、ゾーン名 (Europe/Berlin など) を添えて表示するので、どのレンズが生んだ値かが常に分かります — 判定はブラウザ内で行われるため、ベルリンの訪問者にはベルリン時刻が、東京の訪問者には東京時刻が表示されます。3 行目は完全な IANA タイムゾーンデータベースから選んだ任意のゾーンで、別の場所にあるサーバーのログを読むときに欲しい行です。

  • UTC — すべてのシステムが一致する基準で、保存とログに正しいものです。
  • ローカル — お使いの端末が見るのと同じ瞬間で、判定したゾーンのラベル付きです。
  • 任意に選んだゾーン — 他の場所のマシンのログやトレースを読むためのものです。
  • ISO 8601 — 交換用のテキスト形式で、例えば 2024-05-20T09:33:20.000Z です。
  • 相対 — 「3 時間前」など、どれくらい最近かを手早くつかむためのものです。

オフセット (+03:00、-04:00) は各時刻の横に表示されます。固定ではないからです: ほとんどのゾーンは夏時間のために 1 時間ずれるため、同じゾーンでも時期によって異なるオフセットを生みます。切り替わりの近くの日付こそ、手計算が誤る場所です。

実務でのエポック時刻の扱い

どの言語もシェルも、エポック値を作り読み取る独自の方法を持っています。覚えておく価値があるのは次のものです:

date +%s                         # シェル: 現在時刻を秒で
date -d @1716197600              # シェル (GNU): 秒から日付へ
Date.now()                       # JavaScript: 現在時刻をミリ秒で
new Date(1716197600 * 1000)      # JavaScript: 秒から Date へ
time.time()                      # Python: 秒、浮動小数点で
datetime.fromtimestamp(1716197600, tz=timezone.utc)
SELECT EXTRACT(EPOCH FROM now()) -- PostgreSQL: 秒

ほとんどの日付の苦痛を避ける経験則: 瞬間は UTC として保存・送信し — エポック整数か ISO 8601 文字列で — ローカルのゾーンへの変換は、実際に誰かに表示する最後の瞬間まで行わないことです。早く書式化することが、タイムゾーンのバグを表示層にとどめずデータに焼き込む原因になります。

もう一つ知っておく価値のあること: 符号付き 32 ビットの秒カウンターは 2038 年 1 月 19 日に尽きます。「2038 年問題」です。現代のシステムは 64 ビット値を使い問題ありませんが、古い組み込み機器やレガシーなデータベース列は、まさにそれに出会いうる場所です。

よくある質問

私の数値が秒かミリ秒かをどう判別しているのですか?
その大きさからです: おおよそ 1e11 未満の値は秒として、それより大きければミリ秒として読みます。今日ではこれが 10 桁の秒と 13 桁のミリ秒をきれいに分けます。解釈は結果の横に表示され、ワンクリックで切り替えられるので、推測が隠されることはありません。
「ローカル」とはどのタイムゾーンですか?
お使いの端末が報告するゾーンで、ブラウザ内で判定され、迷わないよう名前で表示されます。サイトのゾーンではなくあなたのゾーンです — ベルリンの訪問者にはベルリン時刻が、東京の訪問者には東京時刻が表示されます。
日付をタイムスタンプに戻せますか?
はい。同じ欄が両方向を受け付けます: 数値を入力すれば日付が、2024-05-20 や 2024-05-20T09:33:20Z のような日付を入力すればエポック値が返ります。切り替えるモードはありません。
1970 年より前の日付も扱えますか?
はい。エポックより前のタイムスタンプは単に負になり — -86400 は 1969 年 12 月 31 日です — 負の値も受け付けて通常どおり変換されます。
タイムスタンプが思っていたのと違う日付を示すのはなぜですか?
ほぼ常に二つの理由のどちらかです: 秒/ミリ秒の解釈が思い込みと違う (ラベルを確認して切り替えてください)、あるいは UTC の値をローカル時刻の期待と比べている、のいずれかです。このツールは両方の行を並べて表示するので、どちらかが分かります。
2038 年問題とは何ですか?
エポック秒を符号付き 32 ビット整数で保存するシステムは、2038 年 1 月 19 日にあふれて負の数に折り返し、1901 年の日付を返します。64 ビット値を使うもの — 現代のほぼすべて — は影響を受けませんが、レガシーな組み込みシステムや古いデータベース列は今もリスクを抱えていることがあります。
入力したタイムスタンプはどこかに送られますか?
いいえ。解析・変換・書式化はすべて、プラットフォーム自身の日付とタイムゾーンのサポートを使ってブラウザ内で動きます。入力した内容が端末の外に出ることはありません。