2024-09-18|閱讀時間 ‧ 約 23 分鐘

如何確保時間格式在前端與後端中的一致性?



在現代跨時區和跨平台的網頁應用程式中,確保日期和時間的統一格式至關重要。本文將介紹如何使用 ISO 8601 標準來設計和實現全球統一的時間格式,在前端與後端應用程式中確保一致性和可靠性。

隨著全球化的發展,跨時區和跨平台的應用程式越來越普遍。日期和時間的格式化和處理成為了開發中不可忽視的重要問題。ISO 8601 是一個被廣泛接受的國際標準,它提供了一種統一的日期和時間表示方法,能夠有效解決時區和格式帶來的混淆。


了解問題核心

如何確保前端和後端在處理日期時間時具有一致的標準,從而減少因為不同時區或格式而引起的混淆和錯誤?

這個問題的核心在於:

  • 前端: 根據使用者所在時區,將本地時間轉換成適合傳送的格式。
  • 後端: 統一接收特定格式的時間,進行驗證,並將其轉換成資料庫可存儲的格式。
  • 資料庫: 存儲統一格式的時間,以便後續查詢和計算。


設計方案

1. 前端

  • 使用者輸入: 提供友善的日期時間選擇器或輸入框,讓使用者直觀地輸入時間。
  • 時區判斷與時間轉換: 將使用者輸入的本地時間,轉換成 UTC 時間 (協調世界時),並以 ISO 8601 格式 (例如:2024-09-18T01:19:43Z) 傳送給後端。ISO 8601 格式是國際標準,明確表示 UTC 時間。(補充:最後面如果是 Z 就代表 UTC +0,如果要其他時區則是:2024-09-18T09:19:43+08:00)


在前端,我們通常使用 JavaScript 來處理日期和時間。為了確保日期時間格式的一致性,我們應該將日期時間格式化為 ISO 8601 字串。JavaScript 提供了內建的方法來實現這一點:

// 取得時間字串
const nowLocal = new Date();
console.log(nowLocal); // Wed Sep 18 2024 09:19:43 GMT+0800 (台北標準時間)

const nowUTC = nowLocal.toISOString();
console.log(nowUTC); // 2024-09-18T01:19:43.124Z

// 恢復時間字串
const pastLocal = new Date('2024-09-18T01:19:43.124Z')
console.log(pastLocal); // Wed Sep 18 2024 09:19:43 GMT+0800 (台北標準時間)

const pastUTC = pastLocal.toISOString();
console.log(pastUTC); // 2024-09-18T01:19:43.124Z


前端送出 API 範例:

當要送出『使用者電腦時區的 0 點 0 分』時,則可以直接使用 toISOString 轉換:

const sendData = () => {
const currentDate = new Date(); // Wed Sep 18 2024 00:00:00 GMT+0800 (台北標準時間)
const isoDateTimeString = currentDate.toISOString(); // 2024-09-17T16:00:00.000Z
const requestData = { startAt: isoDateTimeString };

fetch('/api/data', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(requestData)
})
}


若是要送出『目標(設備)時區的 0 點 0 分』時,則需要指定時區:

const sendData = () => {
const targetTimeZoneDateTime = dayjs.tz('2024-09-18', 'Asia/Taipei').format(); // 2024-09-18T00:00:00+08:00
const currentDate = new Date(targetTimeZoneDateTime); // Wed Sep 18 2024 00:00:00 GMT+0800 (台北標準時間)
const isoDateTimeString = currentDate.toISOString(); // 2024-09-17T16:00:00.000Z
const requestData = { startAt: isoDateTimeString };

fetch('/api/data', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(requestData)
})
}



2. 後端

  • Joi 驗證:
    • 使用 Joi 套件定義嚴格的日期時間驗證規則,確保接收到的時間格式符合 ISO 8601 標準。
Joi.object({
startAt: Joi.date().iso().raw(),
});


3. 資料庫

  • 資料庫存儲:
    • 將解析後的 Date 對象存儲到資料庫中。
    • 建議: 資料庫中存儲的時間字段使用 UTC 時間,避免時區混淆。
    • 注意: 不同資料庫對於日期時間的存儲方式和精度可能不同,需要根據所使用的資料庫進行調整。
  • 時間類型: 選擇適合的資料類型存儲時間,例如:
    • MySQL: DATETIME 或 TIMESTAMP
    • PostgreSQL: TIMESTAMP WITH TIME ZONE
  • 時區設定: 確保資料庫的時區設定為 UTC。


參考資料

  1. 淺談 JavaScript 中的時間與時區處理


分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.