CodeGym /課程 /SQL SELF /用 Unix 時間戳: EPOCH

用 Unix 時間戳: EPOCH

SQL SELF
等級 32 , 課堂 1
開放

Unix 時間就是一種把時間記成一個數字(通常是秒,有時候是毫秒),這個數字是從 1970 年 1 月 1 日 00:00 UTC 到現在過了多少秒。這種格式在開發圈超紅:超好存、超好傳、比大小也超方便,因為它就是個數字而已。

簡單來說,Unix 時間就像一個從 1970 年開始就沒停過的計時器。看到像 1697222400 這種怪數字不用怕——那只是從起點到現在過了多少秒而已。想知道這是什麼日期?等等就教你怎麼算!

這種格式常常用在系統之間同步資料、存時間戳,還有你想要快狠準比一下誰早誰晚的時候。

轉成 Unix 時間

在 PostgreSQL 裡有個超好用的函數 EXTRACT(EPOCH FROM ...),可以把日期或 timestamp 轉成 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 日 00:00(UTC)。

Unix 時間的實戰應用

假設我們有一個 events 表,裡面存著事件資訊,包括 Unix 時間格式的 timestamp。

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

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_TIMESTAMPEXTRACT。這時要先除以 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 時間超適合拿來存時間資料、系統之間傳值、比 timestamp,還有你想讓 CPU 輕鬆一點的時候。API、web 開發、分析、伺服器跟 client 同步都很常用。不過要記得它的特性:都是 UTC、單位可能是秒或毫秒、還有存的格式。

如果你要跟外部系統整合,而對方「講的是 Unix 時間」,現在你已經知道怎麼在 PostgreSQL 處理了。放心用 TO_TIMESTAMPEXTRACT(EPOCH) 來轉來轉去,所有時間的問題都能搞定!

留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION