產生錯誤日期的七個錯誤
epoch 轉換器只做簡單的算術,所以當輸出錯誤時,原因幾乎從來不是數學——而是輸入。時間戳不帶標籤告訴你它是秒還是毫秒、UTC 還是本地、精度如何,而每次錯誤轉換都來自把其中之一猜錯。最快的線索是得出的年份:靠近 1970 年或在數千年之後的日期是單位混淆,而正確但差了整數小時的日期是時區錯誤。下表是現場指南;其後的各節深入解釋單位與時區錯誤,並展示如何在程式碼中驗證一次轉換。
| 錯誤 | 你看到的 | 原因 | 修正 |
|---|---|---|---|
| 把秒當作毫秒讀 | 日期落在 1970 年 | JS 的 Date 和 Date.now() 預期 ms;你傳了 10 位的秒 | 把秒乘以 1000 |
| 把毫秒當作秒讀 | 日期在數千年之後 | 把 13 位值傳給了秒函式 | 先除以 1000 |
| UTC 顯示為本地時間 | 日期對,但時鐘差了你的偏移 | 轉換器預設選了另一個時區 | 把轉換器切到 UTC |
| 複製本地時間卻沒帶偏移 | 在另一台機器上差了數小時 | 儲存了不帶時區的掛鐘時間 | 儲存 UTC 加上時區 |
| 日光節約時間下含糊的掛鐘時間 | 在切換附近恰好差一小時 | 一個出現兩次或從不出現的本地時間 | 從 UTC 轉換;固定 IANA 時區 |
| 把微/奈秒當作秒讀 | 日期在很遠的未來(16 或 19 位) | 資料庫或追蹤的 µs 或 ns 值 | 除以 1,000,000(µs)或 1,000,000,000(ns) |
| 相信顯示出的精度 | 亞秒部分被悄悄丟棄 | 轉換器截斷了毫秒 | 確認目標 API 文件所述的單位 |
epoch 轉換器做什麼
epoch 轉換器把數字時間戳變成可讀日期,並把人類日期轉回 epoch 時間戳。一個好的轉換器處理 Unix 秒、Unix 毫秒、UTC 輸出、本地時區輸出和 ISO 8601 字串,並在你把值複製進程式碼、資料庫或 API 請求之前讓單位一目了然。epoch 轉換器、Unix 時間轉換器、Unix 時間戳轉換器和 Unix epoch 計算機描述的是同一件工作:在自 1970 年 1 月 1 日 UTC 起的秒(或毫秒)計數與人類可讀的日期之間互譯。轉換器很少是問題——問題通常出在輸入。
單位錯誤:秒、毫秒、微、奈
最常見的轉換錯誤就是單位混淆,而且它有一個標誌:日期落在 1970 年,或在數千年之外。JavaScript 是它最常咬人的地方,因為 Date 建構函式和 Date.now() 都以毫秒運作,而大多數 API、資料庫和 Unix 的 date 命令以秒運作。把 10 位的秒值傳給 new Date() 而不乘以 1000,你就早落了 53 年。反過來——把 13 位的毫秒餵給秒函式——會把日期拋向遠方的未來。更高精度的來源讓情況更糟:資料庫常輸出 16 位的微秒,追蹤系統輸出 19 位的奈秒,二者看起來都像有效的 Unix 值,直到它們解碼到錯誤的千年。
- 10 位 → 秒(如 1700000000);13 → 毫秒;16 → 微秒;19 → 奈秒
- JavaScript:new Date(seconds * 1000),或直接 new Date(ms)
- 微秒 → 轉換前除以 1,000,000;奈秒 → 除以 1,000,000,000
- 常識檢查:結果應是當前十年裡一個可信的日期
時區錯誤:UTC vs 本地與日光節約時間
單位一旦正確,剩下的錯誤就是時區錯誤,它們也共享一個標誌:日期正確,但時鐘差了整數小時。Unix 時間戳是一個沒有自身時區的單一時刻;偏移只在格式化該時刻時才套用。所以設為不同時區的兩個轉換器會對同一個數字顯示不同的時鐘時間——誰都沒錯,它們只是顯示不同的本地視角。陷阱在於複製一個本地掛鐘時間卻不記錄它來自哪個時區,或轉換一個落在日光節約時間切換上的時間,那裡一個本地時間可能出現兩次或一次也不出現。當結果恰好差一小時,先懷疑日光節約時間,再懷疑轉換器。
- 在 UTC 中比較值;只在顯示它們的那一刻才套用本地時區
- 切勿在不一併儲存其 IANA 時區或 UTC 偏移的情況下儲存本地時間
- 在日光節約時間切換前後,從 UTC 推導該時刻,而非從含糊的本地時間
先選好方向
大多數時間戳任務朝兩個方向之一進行:epoch 轉日期,或日期轉 epoch。先決定方向可以防止錯誤測試資料和損壞 API 負載的最常見原因——把對的值朝錯的方向轉換。
- epoch 轉日期:貼上 1700000000 並讀取 UTC 或本地日期
- 日期轉 epoch:選擇 2026-01-01 00:00:00 UTC 得到 1767225600
- 複製結果前,確認目標預期的是秒還是毫秒
複製轉換值之前要核對什麼
轉換器只能在輸入無歧義的限度內保持正確。在把時間戳複製進測試、cron 工作、遷移或 API 請求之前,核對單位、時區和預期精度。最快的常識檢查是得出的年份:靠近 1970 年或在遠方未來的日期,幾乎總是表示單位混淆,而非轉換器錯誤。
- 接收系統預期的是秒還是毫秒?
- 顯示的日期是 UTC 還是本地時間?
- 該時間戳表示一個時刻,還是一個本地行事曆日期?
- 資料庫欄位儲存的是原生 datetime、Unix 秒,還是 Unix 毫秒?
- 結果是否靠近 1970 年或在遠方未來——這通常表示單位混淆?
在程式碼中驗證一次轉換
當一個轉換值很重要時——一次遷移、一個計費邊界、一個 cron 排程——不要只信一個工具。在你自己的執行階段裡重新推導同一個時刻,並核對二者在 UTC 中一致。下面每一行都印出一個帶 Z 後綴、毫無歧義的 ISO 8601 字串,因此沒有可比較的本地時區猜測。
- JavaScript: new Date(1700000000 * 1000).toISOString() // '2023-11-14T22:13:20.000Z'
- Python: datetime.fromtimestamp(1700000000, tz=timezone.utc).isoformat()
- Shell (GNU): date -u -d @1700000000 +'%Y-%m-%dT%H:%M:%SZ'
- 如果工具與你的執行階段不一致,可疑的是輸入的單位或時區——而不是轉換器
實例:一個時刻,三種表示
取時刻 2026-01-01 00:00:00 UTC。作為 Unix 秒是 1767225600;作為 Unix 毫秒是 1767225600000;作為 ISO 8601 是 2026-01-01T00:00:00Z。三者描述同一個時刻——只是格式和單位不同。這個時刻從不帶有自身的時區;紐約會把同一個值顯示為 2025-12-31 19:00:00,因為偏移是在顯示時套用的,而非儲存在數字裡。
相關文章
FAQ
- 為什麼我轉換出的日期落在 1970 年?
- 幾乎總是因為把秒當作毫秒來讀了。JavaScript 的 Date 和 Date.now() 使用毫秒,所以傳入 10 位的秒值會落在 1970 年 1 月。請先把秒乘以 1000。
- 為什麼我轉換出的時間恰好差一小時?
- 那是時區或日光節約時間錯誤,而不是計算錯誤。轉換器套用了不同的時區,或本地時間正好落在日光節約時間切換上。把轉換器切到 UTC 看到規範時刻,再套用你真正想要的時區。
- 最適合複製的 epoch 轉換器格式是什麼?
- 對於程式碼,按目標 API 文件所述複製 Unix 秒或毫秒。對於人類,複製帶 Z 或明確時區偏移的 ISO 8601,使該時刻明確無歧義。
- epoch 轉換器和 Unix 時間轉換器一樣嗎?
- 對大多數開發者搜尋而言,是的。epoch 轉換器、Unix 時間轉換器、Unix 時間戳轉換器和 Unix epoch 計算機都在 Unix epoch 時間戳與可讀日期之間轉換。
- 為什麼不同的 epoch 轉換器顯示不同的本地時間?
- 它們套用了不同的時區。底層的 UTC 時刻是相同的;只有本地顯示在變。把轉換器切到 UTC 以比較規範值。
- 我怎麼知道我的數字是秒還是毫秒?
- 數位數。現代的 10 位值是 Unix 秒;13 位值是 Unix 毫秒。如果一個 10 位值在 JavaScript 中落在 1970 年附近,它被當作了毫秒,需要乘以 1000。