前言
在現代 Web 系統中,時間與時區的處理是前後端溝通常見的痛點。若處理不當,容易導致資料錯亂、顯示誤差、跨國用戶體驗不佳。本文將說明:
- 前後端如何正確傳遞與解析時間
- RFC3339 與 ISO8601 差異
- JavaScript 時區處理範例
- UTC 概念與常見誤區
- 實務解法與範例
一、前後端時間溝通的原則
- 統一格式:建議所有 API 傳遞時間皆用字串,並採用標準格式(如 ISO8601/RFC3339)。
- 明確時區:時間字串必須帶時區資訊(如
Z
代表 UTC,或+08:00
代表台北)。 - 儲存與運算用 UTC,顯示時再轉換:資料庫與後端儲存、運算皆用 UTC,前端顯示時再依用戶時區轉換。
範例:API 傳遞時間
{
"createdAt": "2025-05-21T09:30:00Z"
}
二、RFC3339 與 ISO8601 差異
- ISO8601:國際標準時間格式,範例:
2025-05-21T09:30:00+08:00
- RFC3339:是 ISO8601 的子集,專為網路傳輸設計,格式更嚴謹,常見於 JSON、API。
格式 | 範例 | 說明 |
---|---|---|
ISO8601 | 2025-05-21T09:30:00+08:00 | 可省略秒數、時區格式彈性 |
RFC3339 | 2025-05-21T09:30:00Z | 必須完整、嚴格規範 |
注意:RFC3339 格式必須有 T
、時區(Z 或 ±hh:mm),且不可省略。
三、JavaScript 時區處理範例
1. 取得當前 UTC 時間
const nowUtc = new Date().toISOString(); // "2025-05-21T02:00:00.000Z"
2. 解析 RFC3339/ISO8601 字串
const str = "2025-05-21T09:30:00+08:00";
const date = new Date(str);
console.log(date.toISOString()); // 自動轉為 UTC
3. 轉換為本地時區顯示
const utcStr = "2025-05-21T01:00:00Z";
const local = new Date(utcStr);
console.log(local.toLocaleString('zh-TW', { timeZone: 'Asia/Taipei' }));
4. 取得指定時區時間(需用函式庫如 dayjs、luxon)
// 以 dayjs + timezone plugin 為例
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';
dayjs.extend(utc);
dayjs.extend(timezone);
const utcTime = dayjs.utc('2025-05-21T01:00:00Z');
const taipeiTime = utcTime.tz('Asia/Taipei').format('YYYY-MM-DD HH:mm:ss');
console.log(taipeiTime); // 2025-05-21 09:00:00
四、什麼是 UTC?
UTC(協調世界時)是全球統一的時間標準,不受夏令時間、地區影響。所有時區都以 UTC 為基準(如台北為 UTC+8)。
2025-05-21T01:00:00Z
代表 2025/5/21 09:00 台北時間(Z 代表 UTC)- 儲存、運算、API 傳遞皆建議用 UTC
五、常見時區問題與解法
問題1:前端顯示時間錯誤
- 原因:API 傳回無時區資訊,或前端未正確解析
- 解法:API 一律傳回帶時區的 ISO8601/RFC3339 字串,前端用
new Date(str)
解析
問題2:夏令時間錯亂
- 解法:一律用 UTC 儲存,顯示時用函式庫(如 dayjs、luxon)依用戶時區轉換
問題3:多國用戶時間顯示不一致
- 解法:API 傳 UTC,前端根據用戶瀏覽器自動轉換
實務範例:API 設計
{
"startTime": "2025-05-21T01:00:00Z", // UTC
"endTime": "2025-05-21T09:00:00+08:00" // 台北時區
}
前端解析:
const start = new Date(apiData.startTime);
const end = new Date(apiData.endTime);
console.log(start.toLocaleString());
console.log(end.toLocaleString());
結語
時區與時間格式的正確處理,是跨國、跨平台系統不可忽視的細節。建議:
- API 傳遞一律用 RFC3339/ISO8601,帶明確時區
- 儲存、運算皆用 UTC
- 顯示時再依用戶時區轉換
- 善用現代函式庫 dayjs、luxon 處理複雜時區
延伸閱讀: