設計情報

投稿者: SPIRERS ナレッジ向上チーム 2023年10月11日 (水)

日付や時刻を扱う際のタイムゾーンに関する注意点

日時や日付などのフィールドを扱う際にフィールドごとのタイムゾーンの有無によって、日本時間とUTCのずれによって日付や時間がずれる問題が発生する可能性があります。
この記事では、ずれが生じる仕組みやパターンとその対処法について紹介します。

日時フィールドとタイムゾーンについて

日時フィールド、作成日時(_createdAt)、最終更新日時(_updatedAt)にはタイムゾーンの概念があり、DB内ではUTC(協定世界時)で格納されています。
また、抽出条件の条件式やDBトリガの演算式で使用する
NOW()
という関数も、UTCで現在日時を取得します。
一方で日付、月日、時刻など、日時以外のフィールドにはタイムゾーンの概念は存在しません。
※アプリ利用画面上ではユーザ設定で選択されているタイムゾーンに合わせて表示されるため、日本時間とずれて表示されることはありません。

どんな問題が起こるのか

タイムゾーンの概念がある値(日時フィールド、作成日時、最終更新日時、NOW())と、タイムゾーンの概念がないフィールドを組み合わせたときに、日付や時間がずれるということが発生します。
例えば、日本時間はUTC時間と比べて9時間進んでいるため、9時間の時差が生じます。
※タイムゾーンの概念があるもの同士の組み合わせ、タイムゾーンの概念がないフィールド同士の組み合わせは問題ありません。
日時以外のフィールドにタイムゾーンがある値をマッピングした場合
日本時間の9時間前の日付や時間が入ってしまうということが起こります。
日付フィールドに日時フィールドをマッピング
日付がずれて登録されてしまう例
高度な条件設定で日時以外のフィールドとタイムゾーン有りの値を比較した場合
日本時間の9時間前の時間と比較してしまい、意図している動作にならないということが発生します。
※トリガ日との関係抽出やアクセス日との関係抽出などでは、抽出タイムゾーンが計算されたうえで条件判定を行うため、この問題は発生しません。
入金ステータスが「1:未入金」かつ入金締切日が現在の日付より前のレコードにメールを送る設定例
この場合、例えばメール配信日時が日本時間で2023/09/01 08:00:00の場合、NOW()の値は2023/08/31 23:00:002023/08/31となるため、入金締切日を1日だけ過ぎている会員にはメールが配信されなくなってしまいます。

対処方法

関数設定や高度な条件設定で
+ INTERVAL('9 hours')
という記述をすることで、UTC時間から日本時間の9時間をプラスし、日付がずれることを回避することができます。
※日本以外のタイムゾーンに合わせる場合は、UTCとの時差に合わせてプラスマイナスと時間を修正してください。
DBトリガのマッピングの記述例
・現在日時の日付だけを格納する
NOW() + INTERVAL('9 hours')

・作成日時の1か月後の日付を格納する
@DB._createdAt + INTERVAL('1 month') + INTERVAL('9 hours')

高度な条件式の記述例
・入金ステータスが1:未入金かつ入金締切日が現在の日付より前のレコードにメールを送る場合
@status = '1' AND @paymentDue < NOW() + INTERVAL('9 hours')

解決しない場合はこちら コンテンツに関しての
要望はこちら