データベースのレコードやAPIのレスポンスを見ていると、こんな数値を見かけることがあります。

"created_at": 1700000000

これは日時を表す数値で、Unixタイムスタンプと呼ばれています。「2023年11月14日 22:13:20 UTC」を意味しています。日時なのに文字列ではなく数値で保存することには、明確な理由があります。

この記事では、Unixタイムスタンプの仕組みと変換方法、開発現場での使い方を初心者向けに解説します。

Unixタイムスタンプとは?

Unixタイムスタンプ(エポック時間)とは、1970年1月1日 00:00:00 UTC(Unix元期)からの経過秒数を表す整数値です。

なぜ「1970年1月1日」なのか?これは歴史的経緯で、Unixオペレーティングシステムが設計された当時の開発上の都合で決まった基準点です。現在では業界標準として広く使われています。

  • 0 = 1970年1月1日 00:00:00 UTC
  • 1000000000 = 2001年9月9日 01:46:40 UTC
  • 1700000000 = 2023年11月14日 22:13:20 UTC
  • 2000000000 = 2033年5月18日 03:33:20 UTC

タイムスタンプの特徴と注意点

タイムゾーンに依存しない

Unixタイムスタンプは常にUTC基準です。東京(JST = UTC+9)でも、ニューヨーク(EST = UTC-5)でも、同じ瞬間なら同じ数値になります。日時を文字列で保存すると「どのタイムゾーンか」を別途管理する必要がありますが、タイムスタンプはその問題を回避できます。

秒とミリ秒を見分ける

Unixタイムスタンプには「秒単位」と「ミリ秒単位」の2種類があります。

単位桁数の目安
秒(Unix time)10桁1700000000
ミリ秒(Epoch ms)13桁1700000000000

JavaScriptのDate.now()はミリ秒を返しますが、Pythonのtime.time()は秒を返します。言語によって異なるため注意が必要です。

2038年問題とは

32ビット整数でタイムスタンプを保存しているシステムでは、2038年1月19日 03:14:07 UTCにオーバーフローが発生します。この日以降の日時を正しく表現できなくなります。現代の多くのシステムは64ビット整数を使っているため影響しませんが、古いシステムでは対応が必要です。

タイムスタンプの変換方法(コード例)

現在のタイムスタンプを取得する

// JavaScript(ミリ秒)
Date.now()                // 1700000000000
Math.floor(Date.now() / 1000)  // 1700000000(秒に変換)

# Python(秒)
import time
int(time.time())          # 1700000000

# PHP(秒)
time();                   # 1700000000

タイムスタンプ → 日時に変換する

// JavaScript
new Date(1700000000 * 1000).toISOString()
// "2023-11-14T22:13:20.000Z"

new Date(1700000000 * 1000).toLocaleString('ja-JP', {timeZone: 'Asia/Tokyo'})
// "2023/11/15 7:13:20"(JST)

# Python
from datetime import datetime, timezone
datetime.fromtimestamp(1700000000, tz=timezone.utc)
# datetime(2023, 11, 14, 22, 13, 20, tzinfo=timezone.utc)

日時 → タイムスタンプに変換する

// JavaScript
new Date('2023-11-14T22:13:20Z').getTime() / 1000
// 1700000000

# Python
from datetime import datetime, timezone
datetime(2023, 11, 14, 22, 13, 20, tzinfo=timezone.utc).timestamp()
# 1700000000.0

2つのタイムスタンプの差を計算する

const start = 1700000000;
const end   = 1700086400;
const diffSec  = end - start;           // 86400秒
const diffDays = diffSec / 86400;       // 1日

よくある質問(FAQ)

秒とミリ秒の見分け方は?
桁数で判断するのが一番簡単です。2024年時点で秒単位は10桁(1700000000前後)、ミリ秒単位は13桁(1700000000000前後)です。受け取ったタイムスタンプが13桁以上であればミリ秒として扱い、1000で割ると秒に変換できます。
タイムスタンプとタイムゾーンの関係は?
タイムスタンプ自体はタイムゾーンを持たず、常にUTC基準の絶対的な時刻を表します。「2023-11-15 7:13:20 JST」と「2023-11-14 22:13:20 UTC」は同じ瞬間なので、同じタイムスタンプ(1700000000)になります。画面表示のときだけタイムゾーンを適用してローカル時刻に変換するのが一般的な設計です。
2038年問題は自分のシステムに影響しますか?
多くの現代的なシステムは64ビット整数でタイムスタンプを管理しているため、問題ありません。しかし、MySQLのTIMESTAMP型(32ビット)、古いCのtime_tが32ビットのシステム、組み込み機器などでは注意が必要です。DBカラムの型をBIGINTDATETIMEにするだけで回避できます。

まとめ

  • Unixタイムスタンプは1970年1月1日UTCからの経過秒数
  • タイムゾーンに依存せず、あらゆる環境で同じ値になるのが最大の利点
  • 秒単位(10桁)とミリ秒単位(13桁)があり、言語ごとに異なる
  • 32ビットシステムでは2038年問題があるため、64ビット整数で保存する

タイムスタンプの変換を手軽に試したい場合は以下のツールが便利です。