Epoch 時間轉換

Unix timestamp 與日期時間雙向轉換,支援秒與毫秒

目前時間

0

1970-01-01 08:00:00

Timestamp → 日期時間

日期時間 → Timestamp

Unix timestamp 是從 1970-01-01 00:00:00 UTC 起算的秒數,它出現在 log 檔、資料庫的 bigint 欄位、JWT 的 exp、webhook 的 payload 裡,但人眼看不出 1735689600 是哪一天。這個工具把兩個方向都做齊:貼一串數字,看它在你本地時區與 22 個常用時區各是什麼時刻;或反過來挑一個日期時間,拿到秒與毫秒兩種格式。頁面最上方還有一個每秒跳動的當前 timestamp,可以直接複製。

使用步驟

  1. 頁面最上方是當前 Unix timestamp(秒),每秒更新一次,右邊的按鈕可直接複製;下方小字是同一瞬間在你瀏覽器時區的時間。
  2. 「Timestamp → Date」欄位貼入數字。秒或毫秒是自動判斷的,沒有手動切換:去掉前後空白後 10 個字元以內視為秒,11 個字元以上視為毫秒,判斷結果會以「Auto-detected: Seconds / Milliseconds」顯示在結果上方。
  3. 第一列 Local Time 是你這台電腦時區的換算結果,格式固定 YYYY-MM-DD HH:MM:SS、24 小時制、零補位。
  4. 第二列左邊的下拉選單可切換時區:UTC 加上亞洲、歐洲、美洲、大洋洲四組共 22 個選項,預設是 UTC。選項名稱後面括號裡的 UTC+8UTC-4UTC+5:30 是該時區在你輸入的那一刻的實際 offset,不是寫死的常數。
  5. 「Date → Timestamp」用瀏覽器原生的日期時間選擇器,選好之後同時給出秒與毫秒兩列結果。
  6. 每一列右側都有複製按鈕。輸入不是數字時(例如貼進一個日期字串),會顯示 Invalid timestamp。

什麼時候用得上

把 log 或資料庫裡的數字翻成時間

created_at 存成 bigint、Nginx access log 帶 msec、Kafka message 的 timestamp——這些欄位在排查問題時都得先變成人類時間才能對上事件順序。貼進來就有,不必開一個 Python REPL。

確認 JWT 或 session 到底過期了沒

JWT 的 iatexpnbf 都是 epoch 秒。decode 出 payload 後把 exp 貼進來,和最上方跳動的當前 timestamp 一比就知道還剩多久,也能看出簽發端的時鐘是不是偏掉了。

跨時區對客服回報的事故時間

客戶說「早上九點多下單失敗」,但你的 log 是 UTC。把 log 裡的 timestamp 貼進來,再用下拉選單切到客戶所在城市,就能確認那個 UTC 時刻在他那邊是幾點,反過來也能框出要撈的時間範圍。

算出查詢條件或測試資料要用的邊界值

要寫 WHERE created_at >= ? 或準備一筆指定時間的測試資料時,用「Date → Timestamp」挑好日期時間,直接複製秒數或毫秒數填進 SQL、cron 設定或 seed 檔。

限制與注意事項

  • 秒與毫秒的判斷是看**字元數**,不是看數值大小。10 位數涵蓋 2001-09-09 到 2286-11-20 的秒、13 位數涵蓋同一區間的毫秒,所以這個規則在日常範圍內成立;但負號會被算進長度,-1000000000(11 個字元)會被誤判成毫秒,算出 1969-12-20 而不是 1938 年。1970 以前的時間請自己乘 1000 後再貼,或改用另一個方向輸入。
  • 16 位數的微秒 timestamp(Postgres、ClickHouse、部分 tracing 系統的預設精度)不會被辨識,會被當成毫秒算出一個幾萬年後的日期。要用的話先自己除以 1000。
  • 超出 JavaScript Date 可表示範圍(距 epoch ±8,640,000,000,000,000 毫秒,約 ±27 萬年)的數字不會被判為錯誤,而是把 NaN 直接印在結果列上。看到 0NaN-NaN-NaN NaN:NaN:NaN 就是位數多打了。
  • 「Date → Timestamp」這一側沒有時區選單:瀏覽器原生的 datetime-local 一律以你本機時區解讀,而且預設精度是分鐘,秒數固定為 00,所以輸出的秒數一定是 60 的倍數。需要精確到秒,請用另一個方向反推。
  • epoch 本身沒有時區。1735689600 就是宇宙中的某一個瞬間,時區只影響「這個瞬間在誰那邊顯示成幾點」。所以同一個 timestamp 在 22 個選項下會產生 22 個不同的字串,但它們指的是同一刻。
  • Unix time 不含閏秒——它假設每天固定 86,400 秒。因此兩個 timestamp 相減不等於兩個時刻之間真正流逝的 SI 秒數(1972 年以來已插入 27 個閏秒)。日常換算完全沒問題,但別拿它做精密授時或天文計算。

常見問題

為什麼我的時間差了 1000 倍,跑到 1970 年或五萬年後?

秒與毫秒搞混,這是 epoch 相關 bug 的第一名。JavaScript 的 Date.now()、Java 的 System.currentTimeMillis() 給的是毫秒(13 位數);Python 的 int(time.time())、PHP 的 time()、Go 的 Unix()、多數 REST API 與 JWT 給的是秒(10 位數)。把毫秒當秒解讀會得到五萬多年後的日期,把秒當毫秒解讀會得到 1970 年 1 月中的某一天。本工具會依位數自動判斷,但你自己的程式碼不會——寫欄位名稱時把單位標進去(expires_at_ms)能省下很多事。

2038 年問題是什麼?這個工具會受影響嗎?

32-bit signed 整數的上限是 2147483647,對應 2038-01-19 03:14:07 UTC。再加一秒就溢位變成負數,在舊系統上會被顯示成 1901-12-13。這個工具用的是 JavaScript 的 double,沒有這個上限(也因此才能算到幾十萬年)。風險在下游:C 的 32-bit time_t、MySQL 的 TIMESTAMP 欄位(合法範圍只到 2038-01-19)、嵌入式裝置與部分老 API。存長期到期日請改用 DATETIMEBIGINT 或 64-bit time_t

為什麼下拉選單裡倫敦有時候是 UTC+0、有時候是 UTC+1?

因為 DST(日光節約時間)。括號裡的 offset 是用 Intl.DateTimeFormatshortOffset 針對你輸入的那個 timestamp 即時算出來的,不是查一張固定表。所以貼一個七月的 timestamp,London 顯示 UTC+1;貼一個一月的,就變 UTC+0。同理紐約會在 UTC-5 與 UTC-4 之間變動,而 Taipei、Tokyo、Kolkata 這些不實施 DST 的時區全年不變(Kolkata 是 UTC+5:30,半小時 offset 是真的存在的)。

本地時間真的會有「不存在」或「重複」的時刻嗎?

會,而且這是雙向轉換不對稱的根本原因。以 America/New_York 為例,春季往前跳的那天 02:00–02:59 這一小時根本不存在;秋季往後撥的那天 01:00–01:59 會走過兩次,同一個本地時間字串對應兩個相差 3600 的 timestamp。Timestamp → 本地時間永遠只有一個答案,但本地時間 → timestamp 在這兩天會無解或有兩解,瀏覽器會替你選一個,無法指定。排程系統踩到這個坑的典型症狀是:某個任務在換日光節約時間那天沒跑,或跑了兩次。

可以直接貼 ISO 8601 字串嗎?例如 `2026-07-30T12:00:00Z`

不行。Timestamp 欄位只接受數字,貼入日期字串會顯示 Invalid timestamp。要從日期換到 timestamp 請用下面的「Date → Timestamp」,用日期時間選擇器輸入。同樣地,輸出格式固定是 YYYY-MM-DD HH:MM:SS,這裡不會產出帶 TZ 的 ISO 8601 字串。

剛打開頁面時最上面閃了一下 1970-01-01,是壞了嗎?

不是。當前時間刻意等到瀏覽器掛載後才開始讀取,避免伺服器端算出的時間和你電腦的時間不一致導致畫面重繪;在那之前初始值是 0,也就是 epoch 本身。第一個 tick(不到一秒)就會補上正確的值。