ぱんだツールズぱんだツールズ

技術背景

UNIXタイムスタンプとは — プログラムでの日時管理の仕組み

約5分

APIのレスポンスに "created_at": 1713657600 という数字が返ってきて、 「これいつのこと?」と感じた経験はありませんか。このような数値がUNIXタイムスタンプです。 プログラムで日時を扱う際の共通フォーマットとして世界中で使われていますが、 ミリ秒と秒の違いやタイムゾーンの関係で混乱しやすい落とし穴も多くあります。 この記事では仕組みから実践的な使い方・よくある失敗まで、具体的なコード例とともに解説します。

UNIXタイムスタンプとは

UNIXタイムスタンプ(UNIX timestamp)とは、1970年1月1日0時0分0秒(UTC)を起点として、 そこからの経過秒数を整数で表現した値です。この起点のことをエポック(epoch)、 またはUNIX時間の原点と呼びます。

なぜ1970年1月1日が起点になったのでしょうか。UNIXオペレーティングシステムは1969〜1970年頃に開発されており、 設計当時の「近い過去」として1970年1月1日がエポックとして選ばれました。 特別な技術的理由があるわけではなく、設計者の判断による取り決めです。 その後、UNIX系OSが世界標準となったことで、このエポックが事実上のグローバルスタンダードになりました。

たとえば 1713657600 というタイムスタンプは、 エポックから1713657600秒後——つまり2024年4月21日00:00:00 UTCを意味します。 文字列で日時を扱うと「2024/04/21」「April 21, 2024」のようにフォーマットが国やシステムによって異なりますが、 タイムスタンプは単なる整数なのでフォーマットの揺れが一切起きません。 これがコンピューターシステムでUNIXタイムスタンプが広く採用されている最大の理由です。

秒 vs ミリ秒の違いと使い分け

UNIXタイムスタンプには「秒単位」と「ミリ秒単位」の2種類があり、これが混乱の最大の原因です。

単位2024-04-21 00:00:00 UTCの値主な用途
秒(s)1713657600UNIX本来の形式、C言語、Python、shell、多くのAPIレスポンス
ミリ秒(ms)1713657600000JavaScript、ブラウザAPI、Javaの一部

JavaScriptではミリ秒が標準です。Date.now()new Date().getTime()はどちらもミリ秒を返します。 秒単位に変換するには1000で割る必要があります。

// JavaScriptでのタイムスタンプ取得

Date.now() // ミリ秒(例: 1713657600000)

new Date().getTime() // ミリ秒(Date.now()と同じ)

// 秒単位に変換

Math.floor(Date.now() / 1000) // 秒(例: 1713657600)

逆に秒単位のタイムスタンプをJavaScriptのDateに変換する場合は、1000倍してからDateコンストラクタに渡す必要があります。 1000倍を忘れると、1970年1月の日時として解釈されてしまいます。

// 秒タイムスタンプ → Date(1000倍が必要)

new Date(1713657600 * 1000) // 2024-04-21

// 1000倍を忘れた場合(バグ)

new Date(1713657600) // 1970-01-20(誤り)

タイムゾーンとUNIXタイムスタンプの関係

UNIXタイムスタンプ自体はタイムゾーンを含まない絶対的な値です。 世界中のどのコンピューターで同じ瞬間を計測しても、まったく同じ数値になります。 日本(JST = UTC+9)にいようと、ニューヨーク(EST = UTC-5)にいようと関係ありません。

タイムゾーンが必要になるのは、タイムスタンプを「人間が読める日時文字列」に変換する段階です。 同じタイムスタンプ 1713657600 を変換すると:

  • UTC: 2024-04-21 00:00:00
  • JST(UTC+9): 2024-04-21 09:00:00
  • EST(UTC-5): 2024-04-20 19:00:00

このため、APIの設計では「タイムスタンプで受け渡し、表示時にタイムゾーン変換する」パターンが推奨されます。 日時を文字列で渡すと変換前後のタイムゾーンの食い違いによるバグが発生しやすいですが、 タイムスタンプなら常に一意の瞬間を指すため安全です。

よくある落とし穴:2038年問題

2038年問題とは、32bit符号付き整数(int32)でタイムスタンプを格納しているシステムが、 2038年1月19日03:14:07 UTC(= 2147483647秒 = 2^31 − 1)を超えた瞬間にオーバーフローする問題です。 2^31 − 1の次の瞬間、値が負の最小値(−2147483648)に折り返し、 1901年12月13日の日時として誤って解釈されてしまいます。

現代のOS・プログラミング言語の多くは64bit整数を使用しており、 64bitで表現できる最大の日時は西暦2920億年以上先のため実質的に問題ありません。 しかし次のようなケースでは今も注意が必要です:

  • 組み込みシステムや32bitマイコン上のプログラム
  • 古いデータベースの INT(11)(32bit)型カラム
  • C言語で time_t を32bitとして扱う古いライブラリ
  • レガシーな基幹システムや金融系システム

言語別の変換コード例

言語現在時刻をタイムスタンプ(秒)で取得タイムスタンプ → 日時に変換
JavaScriptMath.floor(Date.now() / 1000)new Date(ts * 1000)
Pythonimport time; time.time()datetime.fromtimestamp(ts)
shelldate +%sdate -d @1713657600

JavaScript

// 現在時刻(ミリ秒)

Date.now() // 例: 1713657600000

// 現在時刻(秒)

Math.floor(Date.now() / 1000) // 例: 1713657600

// 秒タイムスタンプ → Dateオブジェクト

new Date(1713657600 * 1000).toISOString() // "2024-04-21T00:00:00.000Z"

Python

# 現在時刻(秒, float)

import time; time.time() # 例: 1713657600.123

# タイムスタンプ → datetimeオブジェクト(ローカルタイム)

from datetime import datetime; datetime.fromtimestamp(1713657600)

# タイムスタンプ → datetimeオブジェクト(UTC)

datetime.utcfromtimestamp(1713657600)

shell(bash / zsh)

# 現在時刻(秒)

date +%s

# タイムスタンプ → 日時文字列(Linux)

date -d @1713657600

# タイムスタンプ → 日時文字列(macOS)

date -r 1713657600

UNIXタイムスタンプ変換ツールの使い方

APIのデバッグ時など「この数値はいつ?」とすぐに確認したい場面では、UNIXタイムスタンプ変換ツールが便利です。コピーした数値を貼り付けるだけで、秒・ミリ秒どちらの形式でも自動判別して日時を表示します。

また、日付計算(今から30日後・特定日までの残り日数)が必要な場合は日付計算ツールも合わせて活用してください。どちらもサーバーへのデータ送信は一切なく、ブラウザ内で完結して動作します。

まとめ

  • UNIXタイムスタンプは1970-01-01 00:00:00 UTC(エポック)からの経過秒数を整数で表した値
  • JavaScriptはミリ秒が標準。秒に変換するには1000で割り、日時に戻すには1000倍してDateに渡す
  • タイムスタンプ自体にタイムゾーンは含まれない。変換時に初めてタイムゾーンが必要になる
  • 2038年問題は32bit整数の上限(2147483647 = 2^31-1)のオーバーフロー。現代の64bitシステムは影響なし
  • 負のタイムスタンプは1970年より前の日時を表す(JavaScript含む多くの環境で正しく扱える)
  • ブラウザ上でのタイムスタンプ確認にはUNIXタイムスタンプ変換ツールが便利

よくある質問

UNIXタイムスタンプとはいつのことですか?

UNIXタイムスタンプは、1970年1月1日0時0分0秒(UTC)を起点(エポック)として、そこからの経過秒数(またはミリ秒数)を整数で表した値です。たとえば2024-04-21 00:00:00 UTCは1713657600という数値になります。OSやプログラミング言語・APIレスポンスなど、コンピューターシステム全般で広く使われる日時の表現方法です。

JavaScriptでUNIXタイムスタンプを取得するには?

JavaScriptではDate.now()でミリ秒単位のタイムスタンプが取得できます(例: 1713657600000)。秒単位に変換するにはMath.floor(Date.now() / 1000)とします。new Date().getTime()もDate.now()と同じくミリ秒を返します。秒単位のUNIXタイムスタンプをDateオブジェクトに変換する場合はnew Date(timestamp * 1000)と1000倍する必要があります。

UNIXタイムスタンプにタイムゾーンの概念はありますか?

UNIXタイムスタンプ自体はUTC(協定世界時)を基準とした絶対値であり、タイムゾーンの概念を含みません。世界中どこで同じ瞬間を計測しても同じ値になります。日本時間(JST = UTC+9)やアメリカ東部時間(EST = UTC-5)などの変換は、タイムスタンプを「人間が読める日時文字列」に変換する際に初めて必要になります。

ミリ秒と秒を間違えるとどうなりますか?

ミリ秒のタイムスタンプ(例: 1713657600000)を秒として扱うと、2^{31}を大幅に超えた値を日付変換にかけることになり、西暦55000年以上という意味不明な日時が表示されます。逆に秒のタイムスタンプ(例: 1713657600)をミリ秒として扱うと、1970年1月の日時として扱われてしまいます。どちらも「明らかにおかしな日時」が表示されるため、ログやデバッガーで確認すれば気づきやすいバグです。

2038年問題とは何ですか?現代のシステムに影響しますか?

2038年問題とは、32bit符号付き整数(int32)でUNIXタイムスタンプを格納している古いシステムが、2038年1月19日03:14:07 UTC(2147483647秒 = 2^31-1)を超えた瞬間にオーバーフローして誤動作する問題です。2000年問題(Y2K)の再来とも呼ばれます。現代のOSや新規開発システムの多くは64bit整数を使用しているため影響を受けませんが、組み込みシステム・レガシーDBのカラム型・古いC言語ライブラリなどは要注意です。

UNIXタイムスタンプを日付に変換するブラウザツールはありますか?

ぱんだツールズのUNIXタイムスタンプ変換ツールを使うと、ブラウザ上で秒/ミリ秒のタイムスタンプを即座に日時文字列に変換できます。タイムゾーン指定にも対応しており、ファイルのアップロードは一切不要です。APIのデバッグ時などにコピー&ペーストするだけで使えます。

負のUNIXタイムスタンプとは何ですか?

負のUNIXタイムスタンプは、1970年1月1日00:00:00 UTCより前の日時を表します。たとえば-86400は1969年12月31日00:00:00 UTCを指します。JavaScriptのDateオブジェクトは負のタイムスタンプも正しく扱えます(new Date(-86400 * 1000)は1969年12月31日を返します)。歴史的な日時データを扱うシステムや、テスト用のエッジケース検証で登場することがあります。

この記事で紹介したツール