Unix 時間戳記代表什麼?
Unix 時間戳記是一個數值,表示某個時刻與固定參考點之間的距離。這個參考點是 1970 年 1 月 1 日 00:00:00 UTC,通常稱為 Unix 紀元。
以秒為單位時,紀元是 0,一秒後是 1,一天後是 86400。把時間表示成連續數值,比拆成年、月、日、時、分欄位更容易跨地區排序與比較。
| Unix 秒 | UTC | 韓國標準時間 KST |
|---|---|---|
-1 | 1969-12-31 23:59:59 | 1970-01-01 08:59:59 |
0 | 1970-01-01 00:00:00 | 1970-01-01 09:00:00 |
1 | 1970-01-01 00:00:01 | 1970-01-01 09:00:01 |
86400 | 1970-01-02 00:00:00 | 1970-01-02 09:00:00 |
1704067200 | 2024-01-01 00:00:00 | 2024-01-01 09:00:00 |
為什麼從 1970 年 1 月 1 日開始?
這不是科學上的「時間起點」,而是 Unix 系統約定的計時原點。原點確定後,之後的時刻可用正數表示,之前的時刻則可用負數表示。
因此,1970 年只是數值起點,不是可表示日期的絕對界線。只要數值與日曆範圍足夠寬,就能表示更早或更晚的日期。例如 -31536000 秒約為紀元前一年。
紀元與時間戳記的差別
紀元是起點,時間戳記則是從該起點量出的數值。「Unix 紀元是 1970-01-01 UTC」與「這筆事件的時間戳記是 1704067200」描述的是不同概念。
秒、毫秒、微秒與奈秒
Unix 時間不一定以秒儲存。需要更細時間間隔的系統會使用毫秒、微秒或奈秒。若省略單位,相同數字可能對應到完全不同的日期。
| 單位 | 符號 | 每秒包含的單位數 | 2024-01-01 00:00:00 UTC |
|---|---|---|---|
| 秒 | s | 1 | 1704067200 |
| 毫秒 | ms | 1,000 | 1704067200000 |
| 微秒 | μs | 1,000,000 | 1704067200000000 |
| 奈秒 | ns | 1,000,000,000 | 1704067200000000000 |
位數只能當作線索
接近目前日期的正值通常是:秒 10 位、毫秒 13 位、微秒 16 位、奈秒 19 位。但歷史日期、遙遠未來、前導零、負號與小數都可能不符合這個規律。應優先採用來源文件標示的單位,再確認轉換日期是否合理。
先檢查是否相差 1,000 倍。 若結果落在 1970 年附近或遠得不合理,請切換秒與毫秒後再次核對。
Unix 值不包含時區
Unix 值代表相對於 UTC 的同一個瞬間,但數字本身不會儲存「韓國」或「紐約」等地區名稱。1704067200 以 UTC 顯示是 2024 年 1 月 1 日 00:00,在韓國則顯示為同日上午 9:00。
因此,「轉換成 KST」是用韓國時鐘顯示同一瞬間,不是把事件移到另一個時刻。切換 UTC 與 KST 時,原始 Unix 值不會改變。
固定 UTC 位移量與地區時區
韓國標準時間目前全年為 UTC+09:00。具有季節性時間調整的地區,不能只加減固定小時數來準確處理所有歷史與未來日期;必須查詢該日期適用的地區規則。
2024-01-01T09:00:00+09:00 這樣包含日期與 UTC 位移量的格式,不同地區的讀者才能解讀成同一瞬間。小數秒與精度
不足一秒的部分可用小數表示。1704067200.5 秒是 2024 年 1 月 1 日 00:00:00 UTC 之後 500 毫秒;同一瞬間也可寫成 1704067200500 毫秒。
更換單位不會提高原始測量精度。把整數秒乘以 1,000 雖能得到毫秒形式的數字,但新增的三個零不代表原始時鐘真的量測到毫秒。請把測量精度與顯示單位分開判斷。
處理奈秒值
奈秒值很長,一般數字格式可能捨入末尾位數。需要精確比較時,請把原值保留為整數字串,並檢查可讀日期保留了多少位小數。
負值與閏秒
負值代表 Unix 紀元之前
-1 秒是 1969-12-31 23:59:59 UTC;同一瞬間在韓國已是 1970-01-01 08:59:59。因此,不能只看 Unix 值的正負號判斷當地日曆年份。
一般 Unix 時間不會另計閏秒
POSIX 類型的 Unix 時間不會為罕見的 UTC 顯示 23:59:60 配置一個普通、獨立的 Unix 秒。當您把兩個時間戳記相減並視為很長的物理經過時間時,必須理解這項差異。
閏秒的處理方式可參考 The Open Group 的 POSIX 時間說明。
什麼是 2038 年問題?
32 位有號整數最多只能把 Unix 秒儲存到 2147483647,也就是 2038-01-19 03:14:07 UTC;再加一秒便超出相同格式可容納的範圍。
這不代表 Unix 時間會在 2038 年終止,而是儲存位元寬度的限制。使用更寬的有號整數即可繼續表示之後的日期。
| Unix 秒 | UTC | 意義 |
|---|---|---|
2147483646 | 2038-01-19 03:14:06 | 仍在 32 位有號範圍內 |
2147483647 | 2038-01-19 03:14:07 | 32 位有號整數最大值 |
2147483648 | 2038-01-19 03:14:08 | 超出 32 位有號範圍 |
若檔案或工具需要保存 2038 年之後的合約日期、生日或長期排程,請確認它支援更寬的整數範圍。
Unix 時間與 ISO 8601 比較
Unix 值精簡、容易排序,但無法直接看出日期,也常被省略單位。ISO 8601 字串較長,卻能同時保留日期、時間與 UTC 位移量。
| 表示法 | 範例 | 優點 | 注意事項 |
|---|---|---|---|
| Unix 秒 | 1704067200 | 精簡且容易排序 | 無法直接看出單位與日期 |
| Unix 毫秒 | 1704067200000 | 可排列一秒內的先後順序 | 與秒混淆會得到完全不同的日期 |
| UTC ISO | 2024-01-01T00:00:00Z | 可讀且明確標示 UTC | 必須保留正確語法 |
| KST ISO | 2024-01-01T09:00:00+09:00 | 可直接看出韓國時間 | 數字位移量不等同於具名時區 |
記錄重要時刻時,建議同時保存 UTC ISO 格式、原始 Unix 值與單位,例如 2024-01-01T00:00:00Z(1704067200 秒)。
避免日期轉錯的核對順序
- 確認數值單位。在來源文件中找出 s、ms、μs 或 ns。
- 比較 UTC 與目標時區。確認 UTC 位移量是否跨越午夜。
- 檢查預期位數。目前的秒值通常是 10 位,毫秒值通常是 13 位。
- 保留小數與正負號。移除任何一項都會指向不同瞬間。
- 分享時標明時區。提供含
Z或數字位移量的日期。
結果落在 1970 年附近
秒可能被當成毫秒,或毫秒被當成秒。切換單位後再次核對。
當地日期相差一天
較晚的 UTC 時間在 UTC 以東地區可能已是隔天。除了時鐘,也要比較年、月、日。
末尾位數改變
很長的奈秒值可能在一般數字格式中失去精度,請與原始整數字串比較。
官方標準與延伸閱讀
地區時區規則可能因政府政策而改變。處理歷史日期或未來排程時,請確認相關日期所適用的 IANA 時區規則。
用轉換器驗證概念
Unix 時間戳記常見問題
Unix 時間戳記使用哪個時區?
參考基準是 UTC。Unix 數值本身不包含韓國、美國等地區時區;選擇的時區只會改變顯示用的日曆與時鐘。
Unix 時間何時等於 0?
Unix 時間 0 是 1970 年 1 月 1 日 00:00:00 UTC,同一瞬間在韓國標準時間為上午 9 點。
10 位時間戳記一定是秒嗎?
不一定。接近目前日期的正值通常以 10 位表示秒,但歷史日期、遙遠未來、前導零與負值都可能打破這個規律。請同時確認來源單位與轉換日期。
Unix 時間計算閏秒嗎?
一般 POSIX Unix 時間不會把閏秒編成一個獨立的 Unix 秒。
所有時間戳記都受 2038 年問題影響嗎?
不會。只有把 Unix 秒儲存在 32 位有號整數時才會遇到這項範圍限制;較寬的整數格式可表示 2038 年之後的日期。
應該分享 Unix 時間戳記還是 ISO 8601 日期?
Unix 值精簡且易於排序;含位移量的 ISO 8601 日期更容易讓人理解。重要時刻建議同時分享原始 Unix 值、單位與 UTC ISO 日期。