手軽屋
ツール一覧

2038年問題と64bit化の対応

公開: 2026-06-16・対象: SRE・組み込み・DB管理者

2038年1月19日03時14分07秒(UTC)、32bit符号付き整数で秒数を保持するシステムでUNIX時間がオーバーフローして1901年12月13日に巻き戻る『2038年問題(Y2038)』。残り12年。現代の主要OS・言語は64bit化済みですが、組み込み機器・レガシーDB・古いファイルフォーマットには確実に残っています。

なぜ2038年1月19日なのか

32bit符号付き整数(int32_t)が表現できる最大値は 2,147,483,647(2の31乗 - 1)。これをUNIXエポック(1970-01-01 00:00:00 UTC)から秒数として加算すると:

# UNIX秒 2,147,483,647 を日時に変換
date -u -d @2147483647 -Iseconds
# → 2038-01-19T03:14:07+00:00

# +1秒すると32bit signed intはオーバーフロー
# → -2,147,483,648(1901-12-13T20:45:52 UTC)

UNIX時間を扱う型 time_t がC言語で32bit signedとして定義されていた歴史的経緯から、この問題は『2000年問題(Y2K)』に次ぐ規模で語られてきました。

現代の主要OS・言語は対応済み

つまり2020年以降にビルドされたLinuxサーバー・最近5年のスマートフォン・主要クラウドはそのままで2038年を越えられます。

今も残るリスクポイント

MySQL TIMESTAMP → BIGINT 移行手順

MySQLのTIMESTAMPカラムを64bit対応のBIGINTまたはDATETIMEに移行する流れ:

-- 既存テーブルを確認
SHOW CREATE TABLE orders;
-- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP

-- ① 移行先カラムを追加
ALTER TABLE orders
  ADD COLUMN created_at_v2 BIGINT UNSIGNED NULL;

-- ② 既存値をコピー(UNIX秒へ)
UPDATE orders SET created_at_v2 = UNIX_TIMESTAMP(created_at);

-- ③ アプリ側を両書きに(writeは新旧両方、readは新カラム優先)

-- ④ 旧カラム削除&リネーム
ALTER TABLE orders
  DROP COLUMN created_at,
  CHANGE COLUMN created_at_v2 created_at BIGINT UNSIGNED NOT NULL;

代替案としてDATETIME(年9999年まで対応)への移行もあります。UTC基準での扱いやすさを優先するならBIGINT、人間が読める形を残すならDATETIME

2026年時点でやるべき点検

  1. 自社プロダクトのDBスキーマ確認information_schema.columnsTIMESTAMPINTを一覧化、UNIX秒を入れているINTがあれば棚卸し。
  2. 2038-01-19以降の日付を扱う処理を実装:30年契約のオプション、長期保存の有効期限など。テストケースに2038-01-20を必ず入れる。
  3. サードパーティライブラリのアップデート:jwt系、time系、log処理系の依存を最新版に。特にC/C++製ライブラリは要確認。
  4. 組み込み機器・IoTデバイスのファームウェア棚卸し:自社で配布しているIoT機器、自社で運用しているスマートメーター・産業機器の対応状況確認。
  5. クラウドベンダーの公式声明確認:AWS・GCP・Azureはいずれも公式に2038年対応宣言済み。ただし利用しているEC2のAMIが古い場合はOS更新を。

64bit time_tの上限はいつ?

64bit符号付き整数の最大値は 9,223,372,036,854,775,807(約9.2×10の18乗)。UNIX秒として日付化すると:

# 64bit time_t の上限
# 約 292,277,026,596 年(西暦292,277,026,596年12月)
# 宇宙の現在の年齢(138億年)よりはるかに先

# つまり実質「永久に安全」

64bit化さえ済めば、再び型変更が必要になることは現実的にありません。今のうちに移行を済ませれば、後の世代に問題を残さないのがUNIX時間の良いところです。

補足

2038年問題の境界値を変換ツールで試す

21474836472147483648 を貼って境界の挙動を確認できます:UNIXタイムスタンプ変換