日期與時間 指南

ISO 8601 日期時間怎麼看?T、Z、UTC、+08:00、時區 Offset 完整指南

標準化日期格式的價值不是看起來專業,而是避免 01/05/26 這種不同國家會讀成不同日期的歧義。

更新日期:

API 很常看到:

2026-08-27T20:00:00+08:00

或:

2026-08-27T12:00:00Z

兩段看起來不同,其實可能代表:

同一個瞬間。

速答:ISO 8601 的 T、Z、+08:00 是什麼?
YYYY-MM-DD 是年月日;T 分隔日期與時間;RFC 3339 / ISO 8601 常見的 Z 表示 UTC offset +00:00+08:00 表示本地時間比 UTC 快 8 小時。因此 2026-08-27T20:00:00+08:002026-08-27T12:00:00Z 指向同一 instant。要注意:+08:00 只是 offset,不等於完整的 Asia/Taipei time-zone 規則。

一、為什麼不用 08/27/2026?

因為不同地區日期順序不同。

例如:

01/05/2026

可能是:

  • January 5;
  • May 1。

ISO 8601 用:

2026-05-01

順序固定:

Year → Month → Day。

ISO 官方也強調這種格式可降低跨文化日期歧義。

二、T 是什麼?

例:

2026-08-27T20:30:00

T 的角色:

分隔 date 與 time。

左邊:

2026-08-27

右邊:

20:30:00

三、Z 是什麼?

RFC 3339:

Z 表示 UTC offset 00:00

例如:

2026-08-27T12:00:00Z

意思是:

2026-08-27 12:00:00 UTC。

四、+08:00 是什麼?

2026-08-27T20:00:00+08:00

表示本地 clock time:

比 UTC 快 8 小時。

換 UTC:

20:00 - 08:00 = 12:00 UTC

所以等同:

2026-08-27T12:00:00Z

五、-08:00 怎麼算?

1996-12-19T16:39:57-08:00

RFC 3339 的經典例子說明,它與:

1996-12-20T00:39:57Z

代表同一 instant。

因為當地時間比 UTC 慢 8 小時。

六、Offset 和 Time Zone 是同一件事嗎?

不是。

Offset

例如:

  • +08:00
  • -05:00

只是某瞬間:

local time - UTC。

Time zone

例如:

America/New_York

包含:

  • 歷史規則;
  • DST;
  • 法律變更。

所以:

-05:00 不等於完整的 New York time-zone identity。

七、為什麼 DST 讓 offset 會變?

某些地區夏令時間:

冬季可能:

UTC-05:00

夏季可能:

UTC-04:00

同一 time zone 在不同日期 offset 不同。

只儲存:

-05:00

無法推算未來/過去所有當地時間規則。

八、台灣的 +08:00 呢?

台灣現行標準時間是 UTC+08:00,現在不採 DST。

但如果你設計全球系統:

不應因為自己的地區沒有 DST 就忽略 DST 問題。

九、沒有 Z 或 offset 會怎樣?

例如:

2026-08-27T20:00:00

它缺少:

  • Z
  • +08:00
  • time-zone identifier

這叫:

local / floating date-time context。

不同程式可能依:

  • 本機時區;
  • API 規格;
  • parser

解讀。

跨系統傳輸時更容易出錯。

十、API 時間為什麼常差 8 小時?

典型情境:

Server 回:

2026-08-27T12:00:00Z

你在台灣看到:

20:00

這不是錯 8 小時。

而是:

UTC 轉成 UTC+08:00。

真正錯誤是把:

  • UTC文字當 local;
  • local文字又加8;
  • 或 Z 被忽略。

十一、儲存 UTC 是不是永遠最好?

對「instant」類資料:

  • createdAt;
  • updatedAt;
  • log time;
  • transaction event;

以 UTC / timestamp 儲存通常很方便。

但「當地民事時間」類資料:

每週一早上 9 點台北上課

只儲存 UTC instant 可能不夠表達 recurring local rule。

要看 domain。

十二、生日不應該硬加時區

生日:

1990-05-20

通常是:

calendar date。

不是:

某個 UTC instant。

如果硬轉午夜 UTC 再轉 local,某些時區可能顯示成前一天。

所以 date-only 和 date-time 要分清楚。

十三、YYYY-MM-DD 很適合純日期

例如:

  • 生日;
  • 截止日;
  • 假日;
  • 帳單日期。

如果不涉及一天中的時間:

不要無必要加入午夜與時區。

十四、小數秒怎麼看?

例如:

2026-08-27T12:00:00.123Z

.123

表示秒的小數部分。

常見:

  • milliseconds;
  • microseconds;
  • 更高精度。

實際支援要看系統。

十五、24:00 可以嗎?

ISO 8601 某些規則可能允許特殊表示,但 RFC 3339 profile 限制 hour 為:

00–23。

網路 API 最安全:

使用 00:00:00 的下一天,而不是自己製造 24:00 parser 相容性問題。

十六、Timestamp 和 ISO 字串如何互換?

同一 instant 可表示為:

Unix

1787832000

RFC 3339 / ISO style

2026-08-27T12:00:00Z

Taipei display

2026-08-27 20:00:00 +08:00

三者可以指向同一時刻。

十七、常見錯誤

錯誤 1

把 Z 當沒有時區。

錯誤 2

看到 +08:00 又手動再加8。

錯誤 3

把 offset 當 time-zone identity。

錯誤 4

生日轉 UTC timestamp。

錯誤 5

API 傳無 offset local time,雙方假設不同。

錯誤 6

使用 01/05/26 這種模糊日期。

十八、推薦 API 做法

Instant

使用:

  • UTC timestamp;
  • 或 RFC 3339 帶 offset。

Date-only

使用:

YYYY-MM-DD

Recurring local schedule

保留:

  • local date/time;
  • IANA time zone;
  • recurrence rule。

不要只存固定 offset。

十九、資料交換前的相容性檢查

收到日期字串時,先確認它是只含日期、local date-time,還是帶有 offset 的完整 instant。只含 2026-08-27 的值不能直接推論成某個時區的午夜;沒有 offset 的 20:00 也不能跨系統當成 UTC。對 API 欄位建立測試案例時,至少包含 Z、正負 offset、午夜、跨日、毫秒與無效日期,並確認 parser 遇到缺少時區資訊時會拒絕或明確標示。

若產品需要未來的排程,儲存 IANA time zone 與 recurrence rule,顯示時才套用當地規則。這能處理夏令時間切換造成的不存在或重複時間;固定保存 +08:00 只足以描述當下 offset,不足以描述所有未來的地區規則。

文件範例也要把語意寫出來:2026-08-27T20:00:00+08:00 描述的是一個帶 offset 的時間點,而 2026-08-27T20:00:00 只是沒有時區的 local date-time。兩者外觀很接近,卻不能在序列化、排序或跨地區顯示時互相替換。測試資料若刻意包含這兩種形式,通常能較早發現前端與後端對欄位契約的不同理解。

二十、FAQ

Z 是什麼時區?

代表 UTC offset +00:00。

+08:00 是台灣時區嗎?

它是 UTC offset;台灣現行時間常為 +08:00,但 offset 本身不是完整 time-zone identifier。

T 可以拿掉嗎?

不同規格/parser可能允許不同格式。API應遵守目標規格;RFC 3339的標準形式使用 T

ISO 8601 和 RFC 3339 一樣嗎?

RFC 3339 是針對網路 timestamp 的 ISO 8601 profile / 子集規範,不是完全等同全部 ISO 8601。

為什麼時間差8小時?

常見是 UTC 與 UTC+08:00 顯示差異。

二十一、延伸閱讀

下一步

API 回來的時間看不懂?

先找 Z±HH:MM,再確認它代表哪個 instant;需要時用 FunnyTools 時間戳記轉換器交叉核對。

重點速記

2026-08-27T12:00:00Z = 2026-08-27T20:00:00+08:00