← 全部文章

Unix 時間 vs POSIX 時間 vs epoch 時間戳:術語詳解

「epoch 時間戳」「Unix 時間」「POSIX 時間」常被混用,在日常程式碼中它們是同一個數字——自 1970-01-01 UTC 起的秒數。但它們的來歷不同:Unix 時間是慣例,POSIX 時間是正式規範(IEEE Std 1003.1),而「epoch」是指任意參考時刻的通用術語。本指南將每個術語對應到其標準,並指出差異(閏秒、範圍、其他 epoch)真正重要的地方。

Unix 時間、POSIX 時間、epoch 時間戳:簡短回答

在日常程式碼中,這三個術語指的是同一個數字:自 1970-01-01 00:00:00 UTC 起的秒數。區別在於它們的來歷。「Unix 時間」是從早期 Unix 和 C 函式庫繼承下來的慣例。「POSIX 時間」是把同一計數寫成正式標準(IEEE Std 1003.1),它把每天固定為正好 86,400 秒。「epoch 時間戳」是三者中最通用的——「epoch」只是一個固定的參考時刻,雖然它幾乎總是指 1970 年的 Unix epoch,但其他系統(NTP、GPS、Windows)從不同的 epoch 起算。下表把每個術語對應到其標準以及它如何處理閏秒。

術語計的是由誰定義閏秒備註
Unix 時間自 1970-01-01 00:00:00 UTC 起的秒數慣例(Unix / C 函式庫)忽略開發者日常使用的名稱
POSIX 時間依固定公式自 epoch 起的秒數IEEE Std 1003.1 §4.16忽略——每天正好 86,400 秒Unix 時間的正式規範版本
epoch 時間戳自固定 epoch(通常是 Unix epoch)起的計數通用術語——epoch 各不相同取決於 epoch/系統「epoch」是參考時刻,並不總是 1970 年
epoch 毫秒自 1970-01-01 UTC 起的毫秒同一 epoch,更細的單位忽略如今為 13 位;JavaScript 和 Java 的預設值

什麼是 epoch 時間戳?

epoch 時間戳是從一個稱為 epoch 的固定參考時刻起測量的數字計數。在開發者的日常用法中,epoch 時間戳通常指 Unix 時間戳:自 1970 年 1 月 1 日 00:00:00 UTC 起的秒數。值為 0 表示正好是 Unix epoch。正值在 1970 年之後;負值在之前。起關鍵作用的詞是「epoch」——它命名起始時刻,其餘只是從那裡開始計數。關於樸素定義以及時間戳 0 的含義,請參閱《epoch 時間詳解》;本文聚焦於這三個相互競爭的名稱如何關聯。

Unix 時間 vs POSIX 時間:標準怎麼說

Unix 時間和 POSIX 時間指的是同一計數,但只有 POSIX 時間是正式規範化的。IEEE Std 1003.1——POSIX 標準——用一條把 UTC 日曆日期轉換為單一整數的明確公式定義了「Seconds Since the Epoch」。該公式的決定性性質是把每天視為正好 86,400 秒(60 × 60 × 24)。這是有意的簡化:它忽略閏秒,以天文精度換取一個便於計算、排序和儲存的值。「Unix 時間」是同一量的口語名稱,早於該標準;當你需要精確定義時,引用的是「POSIX 時間」。

  • POSIX 公式:一個 UTC 日期對應為一個整數,每天固定為 86,400 秒
  • 結果:Unix/POSIX 時間戳跟隨 UTC,但從不計入插入的閏秒
  • time_t 是承載它的 C 型別——歷史上為有號 32 位元,如今通常為有號 64 位元
  • 同一時刻 → 在任何符合標準的系統上都是相同的值,無論時區或地區設定

Unix 時間和 POSIX 時間真的會有差別嗎?

對幾乎所有軟體而言,不會——它們是同一個數字,你可以混用這兩個術語。差別只在民用時間與物理的邊界處顯現。由於兩者都忽略閏秒,Unix/POSIX 時間戳並不是自 1970 年起經過的 SI 秒的真實計數:它不包含自 1972 年以來插入 UTC 的 27 個閏秒。(TAI 是連續的原子時間標度,自 2017 年起恰好領先 UTC 37 秒。)在閏秒前後,POSIX 時鐘會重複或跳過一秒,以使一天保持正好 86,400 秒。大型平台用 leap smearing(閏秒平滑)來避免這種不連續——把多出的一秒分攤到一整天,使任何時間戳都不會含糊。如果你在做高精度計時、跨閏秒排程,或與 GPS 或 TAI 比較,那正是「Unix」與「POSIX」不再只是學術之處,閏秒模型開始重要。

你會遇到的其他 epoch

「epoch 時間戳」之所以表示「Unix 時間戳」,只是出於慣例。epoch 只是時鐘開始計數的那個時刻,而若干廣泛使用的系統從不同的 epoch 起算。當一個值用 Unix epoch 解碼不出 2020 年代的合理日期時,原因往往是另一個 epoch。

  • Unix / POSIX epoch — 1970-01-01 UTC;秒(或 ms/µs)。幾乎處處的預設值
  • NTP epoch — 1900-01-01 UTC;由網路時間協定(RFC 5905)使用
  • GPS epoch — 1980-01-06;GPS 時間沒有閏秒,因此已領先 UTC 漂移(截至 2026 年為 18 秒)
  • Windows FILETIME — 1601-01-01 UTC,以 100 奈秒為間隔計數
  • JavaScript / Java — 是 Unix epoch 但以毫秒為單位,這正是這些值為 13 位的原因

為什麼自 1970 年起的時間戳成為標準

Unix epoch 對早期 Unix 系統很實用,隨著 Unix 理念擴散到 C 函式庫、Linux、資料庫、Web 伺服器和程式語言,它成了慣例。單一數字時間戳比在地化的日期字串更易於排序、比較、傳輸和儲存。當 C 函式庫繼而 POSIX 把該計數標準化後,1970 年就在整個生態中固定下來——這正是為什麼在一個平台上產生的值能在任何其他平台上被一模一樣地解碼。

epoch 時間戳範例

幾個已知值能讓定義更容易記住。

  • 0 = 1970-01-01 00:00:00 UTC
  • 1 = 1970-01-01 00:00:01 UTC
  • 86400 = 1970-01-02 00:00:00 UTC
  • 1700000000 = 2023-11-14 22:13:20 UTC
  • 1767225600 = 2026-01-01 00:00:00 UTC

相關文章

FAQ

epoch 時間和 Unix 時間一樣嗎?
在開發者的常見用法中,是的。epoch 時間通常指 Unix 時間:自 1970-01-01 00:00:00 UTC 起經過的秒數。
Unix 時間的定義是什麼?
Unix 時間定義為自 1970-01-01 00:00:00 UTC 起的秒數,且不計閏秒。
什麼是 POSIX 時間?
POSIX 時間是 Unix 時間的正式規範版本。IEEE Std 1003.1("Seconds Since the Epoch")給出一條精確公式,計自 1970-01-01 00:00:00 UTC 起的秒數,並把每天視為正好 86,400 秒。
為什麼 POSIX 時間忽略閏秒?
這是設計使然。POSIX 公式把一天固定為正好 86,400 秒,使該值便於計算與儲存。其結果是 Unix/POSIX 時間戳跟隨 UTC,但不表示插入其中的閏秒。
POSIX 時間戳是否帶時區資訊?
否。POSIX 時間戳表示一個時刻。只有在把該時刻格式化為可讀日期時才會套用時區。
epoch 時間戳在 Windows、Linux 和 macOS 上一樣嗎?
Unix epoch(1970-01-01 00:00:00 UTC)在現代平台和語言中是一致的,因此同一時刻在任何地方都得到相同的 Unix 時間戳。Windows 內部使用自己的 FILETIME epoch(1601 年),但標準的 Unix 和 POSIX 時間戳使用 1970 年。