前端開發了一段時間,終於也讓我遇到日期時區關卡。(笑)
以下的時區為【+08:00】。
JSON 在日期轉換上嚴守 ISO8601 日期規則,並且一律按世界協調時間 (UTC+0) 傳送,導致伺服器接收到的日期都會是少一天的情形。
伺服器接收 ISO8601 日期
原本伺服器接收到 JSON 後,僅做文字擷取後直接送 SQL Server 資料庫,意外就這樣發生了。
SQL Server 面對 ISO8601 文字格式也僅僅只做「所見即所得」的日期轉換,不會做時區處理。
加上時區文字後:
SQL Server 無法識別時區區塊,導致轉換失敗。這裡值得一提的是在「完成時間」的地方,是完整的 ISO8601 日期格式,看來 SQL Server 已知用火,確實有支援 ISO8601 日期。
既然如此,那就用新日期格式 DateTime2 來試試:
以上可以得知:
- SQL Server 不會對 ISO8601 日期進行時區轉換,僅做日期格式轉換。
- DateTime 格式不支援 ISO8601 時區區塊
- DateTime2 完整支援 ISO8601 日期格式。
資料庫不足的地方只能使用後端程式進行轉換,以 Delphi 為例:
ISO8601 日期文字沒有時區內容時,則 UTC 日期時區偏移 0,本機時區 +08:00。
ISO8601 日期文字有時區內容時,則 UTC 日期時區偏移 -08:00,本機時區時區偏移 0。
結論
如果是新專案,日期格式一律存放 UTC+0 日期,後端不需處理,而前端 JavaScript 會自動轉換對應時區,算是對前後端都很友善的選項。
前端是採用沒有自動轉換時區的開發工具,就辛苦一點手動處理。(攤手)
萬一是承接舊專案,或在已有資料庫的情形建構前端網站,那資料庫日期十之八九都可能會是以該時區日期存放,此時就會建議後端傳送或接收都要進行本機時區轉換。
不知不覺就掃掉全球化的地雷,哈!