在 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
- 標準化:全球通用,不會有「月/日/年」vs「日/月/年」的歧義
- 語言無關:Java、JavaScript、Python、PHP 等都內建支援解析
- 可排序:ISO 8601 字串按字母順序排序就等於時間順序
- 含時區資訊:避免跨時區系統整合時的時間錯誤
- 精確到毫秒:支援
.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 格式,建議策略:
- 使用
DATETIME 或 TIMESTAMP 欄位儲存 UTC 時間
- 程式存入前先轉為 UTC,取出後再依需求轉為目標時區
- Laravel 的
Carbon 類別支援 ISO 8601 解析:Carbon::parse('2020-04-02T08:02:17+08:00')
參考資料