PC・モバイルのトラブル

Unix Timestampの秒とミリ秒:日付が1970年になる理由

Unix timestampを日付にすると1970年付近になる場合、秒をミリ秒として読んでいることがよくあります。単位の見分け方を解説します。

要点

Unix timestampが1970年付近の日付になるなら、単位の取り違えであることが多い。

Unix timestampは秒が一般的で、JavaScriptのDateはミリ秒が一般的だ。

最近の日付では10桁は秒、13桁はミリ秒であることが多い。単位が合わなければ、1,000を掛けるか割る必要がある。

timestampを日付に変換したら1970年1月になった。時計の故障であることはまずない。秒で保存した値をミリ秒として読んだか、その逆だ。

Unix timestampとは

Unix timestampはUnix epoch(1970-01-01 00:00:00 UTC)からの経過時間を表す。一般的には秒単位だ。同じ瞬間をミリ秒(秒 × 1,000)で保存することもある。数字自体に単位は書かれていない。

秒とミリ秒:1,000倍の差

1秒は1,000ミリ秒。1720000000と1720000000000を比べてほしい。前者が秒、後者がミリ秒なら同じ瞬間だ。前者をミリ秒として読むと、日付は1970年側へ飛ぶ。

次のUTC結果は上の数字から計算したもので、推測ではない。

多い単位 解釈(UTC)
1720000000 秒として読むと最近の日付:2024-07-03 09:46:40 UTC
1720000000000 ミリ秒 ミリ秒として読むと同じ瞬間:2024-07-03 09:46:40 UTC
1720000000をミリ秒として 単位が違う 1970年付近:1970-01-20 21:46:40 UTC

なぜ1970年になるのか

秒の値をミリ秒として扱うと、数字は必要な大きさの1,000分の1になる。JavaScriptはUnix epochからごく短い時間だけ進んだと数え、日付は1970年に留まる:

const seconds = 1720000000;

new Date(seconds);
// 1970-01-20 21:46:40 UTC

new Date(seconds * 1000);
// 2024-07-03 09:46:40 UTC

その1970年はepochから約2週間後だ。Dateに渡す前に、秒に1,000を掛ける。

  • 秒 (SECONDS)
  • 1720000000
  • ミリ秒 (MILLISECONDS)
  • 1720000000000
同じ瞬間:秒 × 1,000 = ミリ秒。
  • 秒の値
  • 誤ってミリ秒として扱う
  • 1970年付近の日付
秒をミリ秒として読むとUnix epoch付近に落ちる。
秒か、ミリ秒か?

結果が1970年付近なら、タイムゾーンを疑う前にtimestampの単位を確認する。

10桁は秒、13桁はミリ秒か

最近の日付では、10桁は秒、13桁はミリ秒であることが多い。手がかりであって検証ルールではない。桁数は対象期間で変わり、マイクロ秒やナノ秒のAPIもある。単位は文書か、意味のある日付で確認する。

JavaScriptで特に起きやすい理由

JavaScriptの数値Dateはepochからのミリ秒だ。多くのバックエンド、データベース、Unixツールは今も秒を保存する。秒をそのままDateに渡すのはよくあるバグだ:

const unixSeconds = 1720000000;

const wrong = new Date(unixSeconds);
const correct = new Date(unixSeconds * 1000);

wrongは1970年付近(1970-01-20 21:46:40 UTC)。correctが意図した最近の瞬間(2024-07-03 09:46:40 UTC)。

他のシステムは単位が違うことがある

他の言語、API、データベースは秒にもミリ秒にもなり得る。マイクロ秒やナノ秒のこともある。言語が常に一方だと決めつけず、文書を見る。数がJSONならJSON整形・検証・比較でフィールドは読みやすくなるが、単位までは分からない。

自分のtimestampの単位をどう見分けるか

次の順で確認する。桁数だけでは足りない。

  1. APIまたはデータベースの文書を見る。
  2. およその桁数を見る。
  3. 妥当な最近のtimestampと大きさを比べる。
  4. 秒としてとミリ秒として試す。
  5. 出た日付が妥当か見る。

一方が1970年、他方が見覚えのある日付なら、原因は単位の不一致だ。

Unix timestampでよくある誤り

  • 秒をミリ秒として解釈。 上の例のように日付が1970年側へ折りたたまれる。
  • ミリ秒を秒として解釈。 日付が遠い未来へ飛ぶか、変換が失敗する。
  • 1,000を二度掛ける。 すでにミリ秒の値が巨大になり、日付が何世紀も先になる。
  • 1,000を二度割る。 秒の値がさらに縮み、また1970年付近に戻る。
  • タイムゾーンのせいだと思う。 ゾーンは時刻や暦の日付をずらす。最近のtimestampを1970年にはしない。
  • 整形済みの日付文字列をUnix timestampとして扱う。 2024-07-03T09:46:40Zのような値はepoch数値ではない。秒ではなく日付文字列として解析する。

タイムゾーンが1970年問題の原因か

たいてい違う。タイムゾーンは表示時刻を変え、真夜中付近では暦の日付も変え得る。最近のUnix timestampを1970年にはしない。結果が1970年なら、まず秒とミリ秒を確認する。

Unix timestampを変換して確認する

NEXNARA 日付・時刻コンバーターはブラウザでUnix timestampを変換できる。

Unixの秒またはミリ秒を貼り付け、現在のtimestampを使い、UTCとローカル時刻を見、タイムゾーンを変換し、日付を整形できる。自動判定は10桁を秒、13桁をミリ秒とすることが多い。単位は自分で選べる。

変換そのものはブラウザ内で行われる。このツールは日付やtimestampをNEXNARAのサーバーへ送らない。広告や他のサイト機能はネットワークを使う。それは変換とは別だ。

Unix timestampを確認するなら日付・時刻コンバーターを開き、秒とミリ秒を比べてほしい。

FAQ

Unix timestampが1970年になるのはなぜ?

秒をミリ秒として読んだことが多い。JavaScriptははるかに小さい数として扱うので、日付は1970-01-01 00:00:00 UTCの直後になる。秒に1,000を掛けてから再変換する。

Unix timestampは秒?ミリ秒?

秒が一般的だ。多くのWeb APIとJavaScript Dateはミリ秒を使う。そのシステムの文書を確認する。マイクロ秒やナノ秒のシステムもある。

秒をミリ秒にするには?

1,000を掛ける。1720000000秒は1720000000000ミリ秒。逆は1,000で割る。

JavaScriptのDateはなぜミリ秒?

JavaScriptの数値Date timestampはUnix epochからのミリ秒と定義されている。unixSecondsがUnix秒ならnew Date(unixSeconds)は誤りだ。

10桁のtimestampは常に秒?

いいえ。最近の日付では多いが、13桁はミリ秒が多い。桁数は手がかりであり規則ではない。文書か妥当な日付で確認する。

Unix timestampにタイムゾーンは含まれる?

含まれない。Unix timestampは1970-01-01 00:00:00 UTCから数えた一瞬だ。タイムゾーンは表示の仕方に影響し、数字そのものには入らない。