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 |
小技巧跟常見錯誤
- 精度選錯
如果你的 Unix 時間是毫秒(像 1697222400000),不能直接丟給 TO_TIMESTAMP 或 EXTRACT。這時要先除以 1000:
SELECT TO_TIMESTAMP(1697222400000 / 1000);
結果:
2023-10-13 00:00:00+00
- 忘記時區
Unix 時間是 UTC,所以結果都不會自動考慮時區,除非你自己轉換。例如:
SELECT TO_TIMESTAMP(1697222400) AT TIME ZONE 'Europe/Moscow';
結果:
2023-10-13 03:00:00
- 數字太大搞錯單位
有時候工程師會不小心傳太大的 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_TIMESTAMP 跟 EXTRACT(EPOCH) 來轉來轉去,所有時間的問題都能搞定!
GO TO FULL VERSION