環境
Azureリソース
Web AppsとPaaSのAzure SQL Serverを使用
フレームワーク
フロントエンドをVue.js、バックエンドをNode.jsのExpressで作成
何が起きたか
「登録日時」などのDATETIME型の列に登録した日付の値が、登録したかった値の9時間前になっていました。
注意点その1.DB側のタイムゾーン
GETDATE()
などを用いる際はDBサーバのタイムゾーンを基に時間を取得します。
Azure SQL Serverはタイムゾーンが指定できないかつデフォルトがUTCです。
対応策としてはAT TIMEZONE
を日付型の列やGETDATE()の後ろに付けてあげると、タイムゾーンがTokyoとして扱われます。
画像はUTCのタイムゾーンをTokyoに変更するクエリです。
比較についてはタイムゾーンを考慮しているようです。例えば
2023-06-19 12:00:00
<2023-06-19 16:00:00 +09:00
がFalseになります。
また、システムから登録日時などをINSERTする場合にUTCから+9時間した時刻をパラメータの値にしたうえで、更にAT TIME ZONE
でTOKYOの時刻に変換すると本来の時刻より+9時間された値となってしまいます。
「東京基準の2023年6月19日午前10時」の想定で2023/6/19 10:00:00
を値として登録
↓
AT TIME ZONE
を付与してクエリ実行
↓
2023/6/19 19:00:00 +09:00
と表示され、「東京基準の2023年6月19日午後7時」になってしまう
クエリでAT TIME ZONE
を付与する場合のプラクティス
-
GETDATE()
や日付型の列などに対して漏れなくAT TIME ZONE
を付与する - タイムゾーンの指定なしで日付を列に登録する場合は、UTCの時刻を登録する
-
AT TIME ZONE
を指定してない時の時間がUTC時刻になるように統一する
注意点その2.WEBサーバ(WebApps)側のタイムゾーン
また、WebAppsを用いて稼働させているコンテナのタイムゾーンも同様にUTCであるため、サーバサイド側の処理でシステム時刻を用いるとUTCの時刻を用いて処理を行う事になってしまいます。
dayjsの場合はプラグインをimportすることでタイムゾーンを指定して時刻を扱うことが可能になります。
クエリでAT TIME ZONE
を付与しない場合のプラクティス
-
GETDATE()
などのDBサーバのタイムゾーンに依存する物を使用しない(あるいは時間を+9して使う) -
AT TIME ZONE
を指定してない時の時間がTokyo時刻になるように統一する