Unix 時間戳 0 代表什麼
每個 Unix 時間戳都計數自單一參考點——1970 年 1 月 1 日 00:00:00 UTC——以來經過的時間。在 Unix 的原始定義中單位是秒,所以時間戳 0 正好是 1970 年 1 月 1 日的 UTC 午夜,86400 正好是 24 小時之後。現代系統也使用毫秒、微秒與奈秒,但參考點相同。每個正值表示紀元之後的某個瞬間;每個負值表示之前的瞬間。
為什麼是 1970 年 1 月 1 日?
這個日期由貝爾實驗室的 Unix 開發者在 1970 年代初選定,作為略早於 Unix 本身誕生的實用參考點。它需要足夠早,使一般系統時間戳為正;足夠近,以適配早期電腦的小整數範圍;又足夠簡單,便於心算核對。當 Unix 變得有影響力後,語言、作業系統、資料庫、日誌格式與網路協定都繼承了同一個起點。
- Unix 自 1969 年起在貝爾實驗室開發 —— 紀元設在其稍前
- 選擇 1 月 1 日作為乾淨的日曆邊界
- 用 1970 年而非 1969 年,因為實作使用從零開始的計數器
- 現代所有作業系統、語言與協定都繼承了這個紀元 —— 沒有競爭標準
負時間戳:1970 年之前的日期
負的 Unix 時間戳表示 1970 年 1 月 1 日 00:00:00 UTC 之前的瞬間。大多數現代 64 位系統都能正確支援,這對歷史資料、出生日期、封存記錄,以及與紀元早於 Unix 的系統互通很有用。較舊的函式庫與資料庫可能拒絕負值,因此歷史資料集值得做一次顯式的相容性檢查。
- -1 = December 31, 1969 23:59:59 UTC (one second before the epoch)
- -86400 = December 31, 1969 00:00:00 UTC (one day before the epoch)
- -2208988800 = January 1, 1900 00:00:00 UTC
- JavaScript: new Date(-86400 * 1000).toISOString() → '1969-12-31T00:00:00.000Z'
格式的實際上限
Unix 紀元本身不是上限;儲存型別才是。儲存在 32 位有號整數中的時間戳,會比儲存在 64 位整數、JavaScript 數字或資料庫原生 timestamp 型別中的時間戳早得多地失效。評估時間戳安全性時,既要問使用什麼單位,也要問用什麼數值型別儲存。
- 32-bit signed integer max: 2,147,483,647 = January 19, 2038 03:14:07 UTC (the Year 2038 problem)
- JavaScript Date max: 8,640,000,000,000,000 ms = September 13, 275760 CE
- 64-bit signed integer max: ~9.2 × 10^18 seconds = year ~292 billion
- PostgreSQL TIMESTAMPTZ max: January 1, 294276 CE
其他系統的紀元
Unix 並不是運算中使用的唯一紀元。其他系統出於歷史或技術原因定義了自己的參考點。
- GPS 紀元:1980 年 1 月 6 日 00:00:00 UTC —— 由 GPS 衛星與接收機使用
- Windows FILETIME:1601 年 1 月 1 日 00:00:00 UTC —— 以 100 奈秒為間隔
- Apple Cocoa / NSDate:2001 年 1 月 1 日 00:00:00 UTC
- Excel / Lotus 1-2-3:1900 年 1 月 1 日 —— 為相容 Lotus 而刻意保留的閏年差一錯誤
- FAT 檔案系統:1980 年 1 月 1 日 00:00:00 本地時間
紀元的秒、毫秒、微秒與奈秒
timestamp 這個詞並不總是表明單位。Unix 秒在作業系統與後端語言中常見。Unix 毫秒在 JavaScript 與瀏覽器 API 中常見。微秒與奈秒出現在資料庫、追蹤系統與高解析度日誌中。單位同時決定精度與你看到的位數。
- Seconds: 1700000000 — common in Python, PHP, Go, Ruby, C, and Unix command-line tools
- Milliseconds: 1700000000000 — common in JavaScript Date and many web analytics systems
- Microseconds: 1700000000000000 — common in some databases and event pipelines
- Nanoseconds: 1700000000000000000 — common in high-resolution tracing and systems languages
- Always document the unit when storing epoch values in APIs, CSV files, and database columns
紀元時間 vs UTC vs 本地時間
紀元時間是一個計數。UTC 是定義參考時刻的全球時間標準。本地時間是基於 America/New_York 或 Asia/Tokyo 這類時區的顯示選擇。Unix 時間戳不會因使用者出行而改變;改變的只是格式化的日曆日期與時間。
- 同一個時間戳在不同時區可能顯示為不同的本地日期
- UTC 輸出最適合日誌、API 與跨伺服器偵錯
- 本地輸出最適合日曆、使用者介面與報表
- 時區偏移在格式化時套用,並不儲存在 Unix 時間戳內部
紀元時間常見問題
The Unix epoch (1970-01-01 UTC) was inherited from Multics, the OS that influenced early Unix design. POSIX later standardized the time_t type with explicit semantics that differ from how the original Unix specs described it — and most other platforms count from a different epoch entirely.
- Multics (1969) counted seconds from 1970-01-01 GMT; Unix adopted the same epoch in 1971
- POSIX time_t is defined as a count of seconds since 1970 UTC, explicitly excluding leap seconds (every day is 86,400 ticks)
- POSIX vs Unix terminology: in practice the two are used interchangeably; POSIX is the standardized name
- Other software epochs differ widely:
- Windows FILETIME — 1601-01-01 UTC (Gregorian-cycle start), 100-nanosecond intervals
- .NET DateTime.Ticks — 0001-01-01, 100-nanosecond intervals
- Apple / Core Data — 2001-01-01 UTC (Cocoa reference date), seconds
- NTP — 1900-01-01 UTC, seconds; GPS — 1980-01-06, seconds (no leap seconds)
- Julian Day — noon UT, 4713 BC (proleptic Julian), days
- When importing time data, confirm the epoch before trusting the value as Unix time
Related articles
FAQ
- Is epoch time always in seconds?
- The classic Unix timestamp is seconds since 1970-01-01 00:00:00 UTC, but many systems use milliseconds, microseconds, or nanoseconds with the same epoch.
- Can Unix timestamps represent dates before 1970?
- Yes. Negative timestamps represent dates before the Unix epoch, though older libraries and databases may not support them.
- Does a Unix timestamp include a timezone?
- No. A Unix timestamp represents one instant in UTC. Timezone information is used only when converting that instant into a readable local date.
- What is the maximum Unix timestamp?
- It depends on the storage type, not the epoch. A 32-bit signed integer maxes out at 2,147,483,647 (January 19, 2038), while a 64-bit integer or a JavaScript number reaches hundreds of millions of years. See the Year 2038 problem for the details.