Unix時間(エポック秒・Unixタイムスタンプ)は、協定世界時(UTC)の 1970年1月1日 00:00:00 からの経過秒数で時刻を表す方式です。タイムゾーンに依存しない 1 つの整数で時刻を表せるため、ログ・データベース・API などコンピュータ間の時刻のやり取りに広く使われます。本記事では、Unix時間の定義・秒とミリ秒・タイムゾーンと UTC・ISO 8601・うるう秒・2038年問題を正確に整理します。
1. Unix時間とは — 1970年からの経過秒
Unix時間は、UTC の 1970年1月1日 00:00:00 を起点(これを エポック=epoch と呼びます)とし、そこからの経過秒数で時刻を表します。たとえばエポックそのものは 0、その 1 秒後は 1 です。
例:1700000000 → 2023-11-14T22:13:20Z(UTC)
- 値はふつう整数で、タイムゾーン情報を含みません(常に UTC 基準)。
- 1 日は
86400秒(60×60×24)として数えます。 - 未来の時刻は正の大きな値、エポックより前(1970年より前)は負の値で表します。
- 「Unixタイムスタンプ」「エポック秒」「POSIX時間」もほぼ同じ意味で使われます。
このように時刻を 1 つの数値に落とし込めるため、ソートや差分計算(経過時間=引き算)が非常に簡単になります。
2. 秒とミリ秒 — JavaScript は 1000 倍に注意
本来の Unix時間は秒単位ですが、言語やライブラリによってはミリ秒単位を使います。代表例が JavaScript で、Date.now() や getTime() はミリ秒を返します。
| 単位 | 例(同じ時刻) | 桁数の目安 |
|---|---|---|
| 秒 | 1700000000 | 10 桁 |
| ミリ秒 | 1700000000000 | 13 桁 |
- ミリ秒を秒にする:
Math.floor(Date.now() / 1000) - 秒(例
1700000000)を JavaScript のDateにする:new Date(1700000000 * 1000)
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 を基本に、末尾でタイムゾーンを示します。
- UTC は末尾の
Z(Zulu)で表します:2023-11-14T22:13:20Z。 - 時差つきは
+09:00のように書きます:2023-11-15T07:13:20+09:00(上と同じ瞬間)。 - 日付と時刻の区切りは大文字の
T。ミリ秒は.123のように小数で付けます。
2023-11-14T22:13:20Z と 2023-11-15T07:13:20+09:00 はまったく同じ Unix時間(1700000000)を指します。ISO 8601 は時差を明示できるので、API のやり取りでは曖昧さを避けられます。タイムゾーン指定のない裸の日時文字列は解釈がブレるため避けましょう。
5. うるう秒の扱い — POSIX時間は無視する
地球の自転は一定ではないため、UTC には不定期に うるう秒(leap second)が挿入され、1 分が 61 秒になることがあります。ところが Unix時間(POSIX時間)はうるう秒を無視すると定義されています。
- POSIX の建前では「1 日 = 厳密に 86400 秒」として計算します。実際の UTC のうるう秒は数えません。
- そのため Unix時間は真の経過秒数(SI秒の積算)とは厳密には一致しません。うるう秒の分だけ理論値とずれます。
- 多くのシステムはうるう秒の瞬間に同じ秒値を 2 回使う、または時計をわずかにゆっくり進める(leap smear)などで辻褄を合わせます。
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_t を 64ビットに拡張することです。64ビット符号付き整数なら数千億年先まで表現でき、人類のタイムスケールでは事実上オーバーフローしません。現代の 64ビット OS・言語ランタイムの多くはすでに 64ビットの時刻型を採用しており、新規システムであれば通常は心配いりません。ただし古い 32ビット環境・組み込み機器・過去のデータ形式が残っている場合は、移行の検討が必要です。
よくある質問(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ビットなら数千億年先まで表現できるため事実上問題は解消します。