Contents

ISO 8601 時間格式 XXXX-XX-XXTXX:XX:XXZ

在 API 開發和系統整合中,時間格式的一致性非常重要。ISO 8601 是國際標準的日期時間格式,幾乎所有現代程式語言和框架都支援,是跨系統傳遞時間資料的首選方式。

什麼是 ISO 8601

ISO 8601 是 ISO(國際標準化組織)制定的日期時間表示標準,主要格式為:

1
YYYY-MM-DDTHH:mm:ss±HH:MM

具體範例:

1
2
3
4
2020-04-02T08:02:17Z           # UTC 時間(Z 代表 Zero offset,即 UTC+0)
2020-04-02T08:02:17+08:00      # 台灣時間(UTC+8)
2020-04-02T03:02:17-05:00      # 美東時間(UTC-5)
2020-04-02T08:02:17.345Z       # 含毫秒的 UTC 時間

格式說明

部分 說明 範例
YYYY 四位數年份 2020
MM 兩位數月份(01-12) 04
DD 兩位數日期(01-31) 02
T 日期與時間的分隔符號(固定) T
HH 兩位數小時(00-23) 08
mm 兩位數分鐘(00-59) 02
ss 兩位數秒數(00-59) 17
Z 代表 UTC+0 時區 Z
±HH:MM 時區偏移量 +08:00-05:00

為何 API 設計應使用 ISO 8601

  1. 標準化:全球通用,不會有「月/日/年」vs「日/月/年」的歧義
  2. 語言無關:Java、JavaScript、Python、PHP 等都內建支援解析
  3. 可排序:ISO 8601 字串按字母順序排序就等於時間順序
  4. 含時區資訊:避免跨時區系統整合時的時間錯誤
  5. 精確到毫秒:支援 .SSS 毫秒精度,適合高精度需求

JavaScript 中的使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// 取得目前時間的 ISO 8601 字串(UTC)
const now = new Date();
console.log(now.toISOString());
// 輸出:2020-04-02T00:02:17.345Z

// 解析 ISO 8601 字串
const date = new Date('2020-04-02T08:02:17+08:00');
console.log(date.toISOString());
// 輸出:2020-04-02T00:02:17.000Z(自動轉為 UTC)

// 取得本地時間的 ISO 格式(含時區偏移)
const localIso = new Date().toLocaleString('sv-SE', {
  timeZone: 'Asia/Taipei'
}).replace(' ', 'T') + '+08:00';

Java 中的使用

Java 8 之後提供了 java.time 套件,是處理 ISO 8601 的最佳選擇:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.time.*;
import java.time.format.DateTimeFormatter;

// Instant:代表 UTC 時間點
Instant now = Instant.now();
System.out.println(now.toString());
// 輸出:2020-04-02T00:02:17.345Z

// ZonedDateTime:帶時區的完整時間
ZonedDateTime taipei = ZonedDateTime.now(ZoneId.of("Asia/Taipei"));
System.out.println(taipei.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME));
// 輸出:2020-04-02T08:02:17.345+08:00

// 解析 ISO 8601 字串
ZonedDateTime parsed = ZonedDateTime.parse("2020-04-02T08:02:17+08:00");
Instant utc = parsed.toInstant();
System.out.println(utc);
// 輸出:2020-04-02T00:02:17Z

// 轉換時區
ZonedDateTime tokyo = parsed.withZoneSameInstant(ZoneId.of("Asia/Tokyo"));
System.out.println(tokyo);
// 輸出:2020-04-02T09:02:17+09:00[Asia/Tokyo]

PHP 中的使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
// 輸出 ISO 8601 格式
 = new DateTime();
echo ->format(DateTime::ISO8601);
// 輸出:2020-04-02T08:02:17+0800(注意:PHP 的 ISO8601 常數缺少冒號)

// 符合 RFC 3339 標準(時區有冒號,更通用)
echo ->format(DateTime::RFC3339);
// 輸出:2020-04-02T08:02:17+08:00

// 解析 ISO 8601 字串
 = new DateTime('2020-04-02T08:02:17+08:00');
echo ->getTimestamp(); // Unix timestamp

// Laravel Carbon
use Carbon\Carbon;
 = Carbon::parse('2020-04-02T08:02:17+08:00');
echo ->toIso8601String();

在資料庫中儲存時間

MySQL 不直接支援 ISO 8601 格式,建議策略:

  • 使用 DATETIMETIMESTAMP 欄位儲存 UTC 時間
  • 程式存入前先轉為 UTC,取出後再依需求轉為目標時區
  • Laravel 的 Carbon 類別支援 ISO 8601 解析:Carbon::parse('2020-04-02T08:02:17+08:00')

參考資料