2021/06/18

JSON 和 SQL Server 日期轉換上的時區地雷

前端開發了一段時間,終於也讓我遇到日期時區關卡。(笑)

以下的時區為【+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 會自動轉換對應時區,算是對前後端都很友善的選項。

前端是採用沒有自動轉換時區的開發工具,就辛苦一點手動處理。(攤手)

萬一是承接舊專案,或在已有資料庫的情形建構前端網站,那資料庫日期十之八九都可能會是以該時區日期存放,此時就會建議後端傳送或接收都要進行本機時區轉換。


不知不覺就掃掉全球化的地雷,哈!

See also