前言

在現代 Web 系統中,時間與時區的處理是前後端溝通常見的痛點。若處理不當,容易導致資料錯亂、顯示誤差、跨國用戶體驗不佳。本文將說明:

  • 前後端如何正確傳遞與解析時間
  • RFC3339 與 ISO8601 差異
  • JavaScript 時區處理範例
  • UTC 概念與常見誤區
  • 實務解法與範例

一、前後端時間溝通的原則

  1. 統一格式:建議所有 API 傳遞時間皆用字串,並採用標準格式(如 ISO8601/RFC3339)。
  2. 明確時區:時間字串必須帶時區資訊(如 Z 代表 UTC,或 +08:00 代表台北)。
  3. 儲存與運算用 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 處理複雜時區

延伸閱讀: