Skip to content
ブログに戻る
チュートリアル

PostgreSQLのtimestampカラムには一体何が格納されているのか?

PostgreSQLのtimestampとtimestamptzの内部構造をわかりやすく解説。タイムゾーンの落とし穴と、ユースケースに応じた正しい型の選び方を紹介します。

6分で読めます

PostgreSQLのtimestampカラムには一体何が格納されているのか?

PostgreSQLの timestamptimestamptz は、どちらも1つの64ビット整数として格納されています。その値は1970-01-01 00:00:00 UTCからのマイクロ秒数です。違いが現れるのは、データを人間が読める形式にフォーマットするときだけです。

なぜハマりやすいのか?

  • 2つのカラムに同じ日付を入れたのに、クエリ結果が違う
  • あなたのアプリは 2025-07-29 10:00 を挿入したのに、別のチームでは 02:00 と表示される
  • フロントエンドのISO文字列がバックエンドのログと一致しない

2つの桃缶:ラベルなしとラベル付き

データ型正式名称格納値SELECT時の振る舞い
timestamptimestamp without time zone生のマイクロ秒カウントそのまま返却 ― Postgresはタイムゾーンを推測しない
timestamptztimestamp with time zone同じマイクロ秒カウントPostgresがセッションの TimeZone 設定を適用してからテキストを送信

たとえ話

  • timestamp = 産地ラベルのない桃の缶詰。中身がフルーツだとわかっても、どこで缶詰にされたかはわからない。
  • timestamptz = 「原産地 UTC+9(JST)」と印刷された桃の缶詰。開ける人は自分で栄養表示を換算するかどうか決められる。

内部構造:ただの巨大な数値

2000-01-01 00:00:00 UTC  → 0
2000-01-01 00:00:01 UTC  → 1 000 000
  • 単位:マイクロ秒(100万分の1秒)
  • 範囲:紀元前4713年〜西暦294276年
  • timestamptimestamptz のストレージは完全に同一。解釈の仕方だけが異なる

15秒で試せるデモ

-- クライアントは東京時間(JST)を使用
SET TimeZone = 'Asia/Tokyo';

CREATE TABLE demo (
  created_ts timestamp,
  created_tz timestamptz
);

INSERT INTO demo VALUES ('2025-07-29 10:00', '2025-07-29 10:00');
クエリ結果理由
SELECT created_ts FROM demo;2025-07-29 10:00:00生の値がそのまま返される。タイムゾーン計算なし
SELECT created_tz FROM demo;2025-07-29 10:00:00+09出力時にタイムゾーンラベルが付与される
SET TimeZone = 'UTC'; のあとSELECT2025-07-29 01:00:00+00同じ瞬間を、別のレンズで見ている

よくある落とし穴と対処法

1. ユーザーごとに違う時刻が見える

  • 原因:クライアントごとに異なる TimeZone 設定で timestamptz を読んでいる
  • 対処:すべて timestamp にして1つのタイムゾーンで統一するか、接続初期化時に SET TimeZone = 'UTC' を強制する

2.「壁時計の時刻」を保存するのに型を間違えた

  • 業務カレンダー(営業時間、締切日)には timestamp を使う
  • 国際的なワークフロー(注文、ログ)は UTCtimestamptz に格納する

3. APIのタイムゾーンがずれる

  • timestamptz は常にISO-8601形式でオフセット付き(Z または +09:00)の文字列として送信する
  • UIはユーザーのローカルタイムゾーンに合わせてフォーマットする

早見表:どちらを使うべき?

ローカルの予定表だけ → timestamp
グローバルに扱うもの → timestamptz(UTCで格納)
  • 会計レポート、授業スケジュール → timestamp
  • 監査ログ、ECの注文データ → timestamptz

Go Toolsで手軽に検証

やりたいことツール使い方
SQLのエポック値を確認タイムスタンプ変換ツール1690622400 を貼り付けて変換
2つのタイムゾーンをひと目で比較タイムゾーン変換ツール10:00 Asia/Tokyo と入力
時間フィールドを含むJSONを整形JSONフォーマッターデータを貼り付けて整形・確認

すべてのツールはブラウザ上で完全に動作します。データがあなたのマシンを離れることはありません。

まとめ

  • PostgreSQLの2つの時間型はどちらもマイクロ秒カウンター。ラベルの有無だけが違い
  • 型を間違えると、混乱するタイムスタンプと誤った計算の原因になる
  • 適切なツールでテスト・変換・検証すれば、何時間ものデバッグ時間を節約できる