CodeGym /コース /SQL SELF /Unix時間の扱い方: EPOCH

Unix時間の扱い方: EPOCH

SQL SELF
レベル 32, レッスン 1
使用可能

Unix時間って、1970年1月1日0時(UTC)から何秒(たまにミリ秒)経ったかを数字で表すだけの方法なんだ。開発の現場ではめっちゃ使われてて、保存も転送も比較も超ラク。だってただの数字だもん。

ざっくり言うと、Unix時間は1970年から動き続けてるタイマーみたいなもの。1697222400みたいな変な数字見たことある?ビビらなくてOK、それは単に起点から何秒経ったかってだけ。これが何の日付か知りたい?もうすぐ計算方法を教えるよ!

このフォーマットは、システム間のデータ同期やタイムスタンプの保存、何が先に起きたかをサクッと比較したいときによく使われる。

Unix時間への変換

PostgreSQLにはEXTRACT(EPOCH FROM ...)っていう専用関数があって、日付やタイムスタンプをUnix時間に変換できるよ。

今の日時をこのフォーマットに変換してみよう:

SELECT EXTRACT(EPOCH FROM NOW());

結果はこんな感じ:

1697222400

この結果は、1970年から今までの秒数だよ。

固定の日付を変換する場合はこう:

SELECT EXTRACT(EPOCH FROM TIMESTAMP '2023-10-01 12:00:00');

結果:

1696152000

これで、2023年10月1日12:00(UTC)がこの値に対応してるってわかったね。

Unix時間からの変換

もちろん、逆変換の関数もある。Unix時間を人間が読める日付に戻したいときはTO_TIMESTAMP()が便利!

Unix時間を日付と時刻に変換してみよう:

SELECT TO_TIMESTAMP(1697222400);

結果:

2023-10-13 00:00:00+00

これで2023年10月13日0:00(UTC)ってわかるね。

Unix時間の実践的な使い方

例えば、eventsっていうテーブルがあって、イベント情報と一緒にUnix時間でタイムスタンプを保存してるとしよう。

CREATE TABLE events (
    id SERIAL PRIMARY KEY,
    event_name TEXT,
    event_time BIGINT -- Unix時間を保存する用
);

このテーブルにデータを入れるとき、Unix時間でタイムスタンプを指定できる:

INSERT INTO events (event_name, event_time)
VALUES
('サーバー起動', 1697222400),
('データベース更新', 1697308800);

この情報を読みやすい形に変換したいなら、TO_TIMESTAMPを使えばOK:

SELECT event_name, TO_TIMESTAMP(event_time) AS readable_time
FROM events;

結果:

event_name readable_time
サーバー起動 2023-10-13 00:00:00+00
データベース更新 2023-10-14 00:00:00+00

コツとよくあるミス

  1. 精度の選択ミス

もしUnix時間がミリ秒単位(例:1697222400000)だったら、そのままTO_TIMESTAMPやEXTRACTに渡しちゃダメ。こういう場合は1000で割る必要がある:

SELECT TO_TIMESTAMP(1697222400000 / 1000);

結果:

2023-10-13 00:00:00+00
  1. タイムゾーンを無視すること

Unix時間はUTC基準だから、特に変換しない限りタイムゾーンは考慮されないよ。例えば:

SELECT TO_TIMESTAMP(1697222400) AT TIME ZONE 'Europe/Moscow';

結果:

2023-10-13 03:00:00
  1. 大きすぎる数字の問題

たまに開発者がうっかりミリ秒のUnix時間(秒じゃなくて)を渡しちゃうことがある。これだと変な結果になる:

SELECT TO_TIMESTAMP(1697222400000); -- エラーになるよ!

直すには、ちゃんと1000で割ろう。

例:タスクの経過時間を計算する

実際のケースで、tasksっていうタスクテーブルがあって、各タスクが作られてからどれくらい経ったかを計算したいとしよう。

テーブルを作る:

CREATE TABLE tasks (
    id SERIAL PRIMARY KEY,
    task_name TEXT,
    created_at TIMESTAMP DEFAULT NOW()
);

いくつかタスクを追加:

INSERT INTO tasks (task_name)
VALUES
('タスク 1'),
('タスク 2'),
('タスク 3');

次に、Unix時間のカラムを追加してみよう:

SELECT id, task_name, EXTRACT(EPOCH FROM created_at) AS created_epoch
FROM tasks;

結果:

id task_name created_epoch
1 タスク 1 1697222400
2 タスク 2 1697233200

そして、作成から何秒経ったかを計算:

SELECT id, task_name, EXTRACT(EPOCH FROM NOW()) - EXTRACT(EPOCH FROM created_at) AS elapsed_seconds
FROM tasks;

結果:

id task_name elapsed_seconds
1 タスク 1 3600
2 タスク 2 7200

いつ、なんでUnix時間を使うの?

Unix時間は、システム間で値をやり取りしたり、タイムスタンプを比較したり、CPU負荷を最小限にしたいときにピッタリ。APIやWeb開発、分析、サーバー・クライアントアプリの同期などでよく使われてる。ただし、UTC基準なこと、単位(秒かミリ秒か)、保存フォーマットの違いには注意しよう。

もし外部システムと連携する必要があって、そのシステムが「Unix時間で話してる」なら、もうPostgreSQLでどう扱えばいいかわかるよね。TO_TIMESTAMPとEXTRACT(EPOCH)をガンガン使って変換すれば、時間系の課題は全部クリア!

2
タスク
SQL SELF, レベル 32, レッスン 1
ロック未解除
時間間隔の計算
時間間隔の計算
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION