跳到主要內容

← 返回部落格

Unix 時間戳完整教學(秒、毫秒、時區怎麼換算)

只要處理過日誌、資料庫或 API,你一定看過像 1700000000 這種數字代表某個日期。那就是 Unix 時間戳,搞懂它能省掉一整類與時間有關的 bug。這篇給你完整全貌。

同一個瞬間,兩個答案。 在我們的時間戳轉換器輸入 1700000000,它同時給你兩行:

Local: 2023-11-15 06:13:20
UTC: 2023-11-14 22:13:20

注意日期不一樣 —— 這個瞬間在 UTC 是 11 月 14 日,在 UTC+8 是 11 月 15 日。這是刻意並排顯示的,因為幾乎每一個時間戳 bug 都是有人看了本地時間的呈現、卻以為那是 UTC。10 位數是秒,13 位數是毫秒;把毫秒餵給以秒為單位的解讀器,會跑到公元 55839 年。

什麼是 Unix 時間戳?

Unix 時間戳是指從 Unix 紀元(1970 年 1 月 1 日 00:00:00 UTC)起算所經過的秒數。因為它從一個固定的 UTC 時間點起算,所以是一個在全世界都代表同一瞬間的絕對數字,與時區無關。

這個特性正是系統喜歡它的原因:兩台位於不同國家的伺服器可以直接比較時間戳,完全不用做時區換算。

秒 vs 毫秒

這是最常見的混淆來源。不同平台用不同單位:

  • —— 10 位數,例如 1700000000。常見於 Unix 工具、資料庫與許多 API。
  • 毫秒 —— 13 位數,例如 1700000000000。JavaScript 的 Date.now() 回傳這個。

一個口訣:10 位是秒、13 位是毫秒。如果換出來的日期落在 1970 年附近,你大概是把毫秒當秒(或反過來)傳了。我們的時間戳轉換工具會依位數自動判斷單位,不用你猜。

時區與 UTC

時間戳本身沒有時區 —— 它是一個絕對的瞬間。時區只在你顯示它時才有意義。同一個時間戳 1700000000 是:

  • UTC 的 2023-11-14 22:13:20
  • UTC+8(台北)的 2023-11-15 06:13:20

兩者是同一刻,只是以不同時區呈現。除錯時務必確認顯示的時間屬於哪個時區 —— 我們的工具會同時顯示你的本地時間與 UTC,避免出錯。

同一組時間戳丟進我們自己的時間戳轉換器的結果如下。產生這張表的機器設定在 UTC+8,所以每一列的本地時間都比 UTC 快八小時 —— 而那個時差正是「兩行一起顯示」的全部意義。

時間戳我們的轉換器顯示
0本地時間:1970-01-01 08:00:00 UTC:1970-01-01 00:00:00
1000000000本地時間:2001-09-09 09:46:40 UTC:2001-09-09 01:46:40
1700000000本地時間:2023-11-15 06:13:20 UTC:2023-11-14 22:13:20
1767225600本地時間:2026-01-01 08:00:00 UTC:2026-01-01 00:00:00
2147483647本地時間:2038-01-19 11:14:07 UTC:2038-01-19 03:14:07
2147483648本地時間:2038-01-19 11:14:08 UTC:2038-01-19 03:14:08

在程式中轉換

大多數語言的轉換都很直接:

// JavaScript(毫秒)
const now = Date.now();               // 1700000000000
const date = new Date(1700000000000); // Date 物件
const seconds = Math.floor(Date.now() / 1000);
# Python(秒)
import time
now = int(time.time())                # 1700000000
from datetime import datetime, timezone
dt = datetime.fromtimestamp(1700000000, tz=timezone.utc)

注意 JavaScript 用毫秒,而 Python 的 time.time() 回傳秒 —— 這又是一個要把單位分清楚的理由。

2038 年問題(簡述)

把時間戳存成有號 32 位元整數的系統,會在 2038 年 1 月 19 日溢位。現代系統改用 64 位元整數,把上限推到幾千億年後,所以今天很少需要擔心 —— 但值得知道為什麼要有 64 位元時間。

最後兩列就是 2038 那道邊界。2147483647本地時間:2038-01-19 11:14:07 UTC:2038-01-19 03:14:07;再加一秒,我們的轉換器給 本地時間:2038-01-19 11:14:08 UTC:2038-01-19 03:14:08,完全沒有抱怨。這一點值得講精確:算術本身沒問題,因為 JavaScript 用雙精度浮點存這個值。2038 問題根本不是算術問題,是儲存問題 —— 一個有號 32 位元整數放不下 2147483648。任何把那個欄位當 int 讀的東西都會繞回負數,掉到 1901 年。

快速換算

想馬上檢查一個時間戳?把它貼進免費的 Unix 時間戳轉換工具,即可看到本地與 UTC 日期、把日期反轉成時間戳,或複製目前的時間戳。它在瀏覽器執行,不需連網。