Unix時間とは — エポック秒・タイムゾーン・2038年問題

Unix時間(エポック秒・Unixタイムスタンプ)は、協定世界時(UTC)の 1970年1月1日 00:00:00 からの経過秒数で時刻を表す方式です。タイムゾーンに依存しない 1 つの整数で時刻を表せるため、ログ・データベース・API などコンピュータ間の時刻のやり取りに広く使われます。本記事では、Unix時間の定義・秒とミリ秒タイムゾーンと UTCISO 8601うるう秒2038年問題を正確に整理します。

結論を先に:Unix時間は UTC の 1970-01-01 00:00:00 を 0 とした経過秒です。タイムスタンプ自体に時差は含まれず、表示するときだけタイムゾーンに変換します。32ビットで保持しているシステムは 2038年に上限へ達するため、64ビット化が必要です。

1. Unix時間とは — 1970年からの経過秒

Unix時間は、UTC の 1970年1月1日 00:00:00 を起点(これを エポック=epoch と呼びます)とし、そこからの経過秒数で時刻を表します。たとえばエポックそのものは 0、その 1 秒後は 1 です。

例:17000000002023-11-14T22:13:20Z(UTC)

このように時刻を 1 つの数値に落とし込めるため、ソートや差分計算(経過時間=引き算)が非常に簡単になります。

2. 秒とミリ秒 — JavaScript は 1000 倍に注意

本来の Unix時間は単位ですが、言語やライブラリによってはミリ秒単位を使います。代表例が JavaScript で、Date.now()getTime()ミリ秒を返します。

単位例(同じ時刻)桁数の目安
170000000010 桁
ミリ秒170000000000013 桁
取り違えに注意。秒とミリ秒を混同すると、時刻が約 1000 倍ずれます(たとえば秒の値をミリ秒として解釈すると 1970年代の値になります)。値の桁数(秒=10桁、ミリ秒=13桁が目安)で確認すると安全です。

3. タイムゾーンと UTC — 値は UTC、表示で変換

Unix時間で最も誤解されやすい点が、タイムゾーンとの関係です。タイムスタンプ自体は常に UTC 基準で、時差の情報は含まれていません。「日本時間か UTC か」は、その数値を人が読む形式に変換して表示するときに初めて関係します。

たとえば 1700000000 という同じ値でも、表示するタイムゾーンによって見た目が変わります。

タイムゾーン同じ値 1700000000 の表示
UTC(±0)2023-11-14 22:13:20
日本時間(JST, UTC+9)2023-11-15 07:13:20

JST は UTC より 9 時間進んでいるので、表示は +9 時間されますが、元のタイムスタンプの数値は変わりません。サーバ間では UTC のタイムスタンプでやり取りし、ユーザーに見せる直前にローカルタイムゾーンへ変換するのが定石です。

4. ISO 8601 表記 — 人間が読む標準形式

Unix時間は機械には便利ですが、人にはそのままだと読めません。そこで、日時を文字列で表す国際標準 ISO 8601 がよく併用されます。形式は YYYY-MM-DDThh:mm:ss を基本に、末尾でタイムゾーンを示します。

ポイント:同じ瞬間でも、2023-11-14T22:13:20Z2023-11-15T07:13:20+09:00まったく同じ Unix時間1700000000)を指します。ISO 8601 は時差を明示できるので、API のやり取りでは曖昧さを避けられます。タイムゾーン指定のない裸の日時文字列は解釈がブレるため避けましょう。

5. うるう秒の扱い — POSIX時間は無視する

地球の自転は一定ではないため、UTC には不定期に うるう秒(leap second)が挿入され、1 分が 61 秒になることがあります。ところが Unix時間(POSIX時間)はうるう秒を無視すると定義されています。

実務上の意味:通常のアプリではうるう秒を意識する必要はほとんどありません。ただし、ナノ秒単位の厳密な計測や、うるう秒をまたぐ瞬間の挙動が問題になる用途(金融・科学計測など)では、システムごとの扱いの違いに注意が必要です。

6. 2038年問題 — 32ビットのオーバーフロー

多くの古いシステムは、Unix時間を time_t という32ビットの符号付き整数で保持していました。符号付き 32ビットで表せる最大値は 2147483647(約 21 億)です。Unix時間がこの値に達するのが、2038年1月19日 03:14:07 UTC です。

この上限を 1 秒超えると、整数がオーバーフローして負の最小値に巻き戻り、時刻が 1901年12月13日 あたりへ飛んでしまいます。これが 2038年問題(Year 2038 problem / Y2K38)です。

項目32ビット符号付き64ビット符号付き
表せる最大の Unix時間2147483647約 9.2×1018
上限に達する時刻2038-01-19 03:14:07 UTC約 2900 億年後
超えたときの挙動負値へ巻き戻る(1901年)事実上問題なし
対策64ビット化が必要解決済み

解決策はシンプルで、time_t64ビットに拡張することです。64ビット符号付き整数なら数千億年先まで表現でき、人類のタイムスケールでは事実上オーバーフローしません。現代の 64ビット OS・言語ランタイムの多くはすでに 64ビットの時刻型を採用しており、新規システムであれば通常は心配いりません。ただし古い 32ビット環境・組み込み機器・過去のデータ形式が残っている場合は、移行の検討が必要です。

Free Tool Unixtime 変換ツールで実際に試す Unix時間(秒・ミリ秒)と日時を相互変換し、UTC とローカルタイムゾーンの表示を確認できます。ブラウザ内で完結します。

よくある質問(FAQ)

Unix時間とは何ですか?

Unix時間(エポック秒、Unixタイムスタンプ)とは、協定世界時(UTC)の 1970年1月1日 00:00:00 を起点(エポック)とし、そこからの経過秒数で時刻を表す方式です。タイムゾーンに依存しない単一の整数で時刻を表せるため、ログ・データベース・API などコンピュータ間での時刻のやり取りに広く使われます。たとえば 1700000000 は 2023-11-14T22:13:20Z(UTC)を表します。

Unix時間は秒ですか、ミリ秒ですか?

本来の Unix時間は『秒』単位です。一方、JavaScript の Date.now() や getTime() は『ミリ秒』単位で値を返すため、秒に変換するには 1000 で割る必要があります。逆に秒のタイムスタンプを JavaScript の Date に渡すときは 1000 を掛けてミリ秒にします。秒とミリ秒を取り違えると約1000倍ずれるため、桁数(秒は10桁、ミリ秒は13桁が目安)で確認すると安全です。

2038年問題とは何ですか?

2038年問題とは、Unix時間を 32ビットの符号付き整数で保持しているシステムが、2038年1月19日 03:14:07 UTC を過ぎると値がオーバーフローし、負の値(1901年など)に巻き戻ってしまう問題です。32ビット符号付き整数で表せる最大値は 2147483647 で、これがちょうどその時刻に対応します。対策は time_t を 64ビットに拡張することで、64ビットなら数千億年先まで表現できるため事実上問題は解消します。

← 技術ブログ一覧へ戻る