時刻制御はよくハマる

Webアプリケーションを作っていて「あれ、9時間前の時刻なんだけど・・・」みたいなことありませんか?
私はよくあります、というかよく見かけて修正します・・・

なぜ起きるのか?

JST時刻だと思って表示したらUTC時刻でした!というだけなのですが・・・これ、意識しないとなかなか面倒なんですよね。

例えば、基本的にプログラム上で明示的にタイムゾーンの指定をしていない場合には以下のように動作します。

Web画面(クライアント側)PCのタイムゾーンの時刻
バックエンド(サーバー側)サーバーOSに設定されているタイムゾーンの時刻

この時に

Web画面(クライアント側)PCのタイムゾーンがAsia/Tokyo(=日本(JST)時間)
バックエンド(サーバー側)サーバーOSに設定されているタイムゾーンがAsia/Tokyo(=日本(JST)時間)

であれば、Web画面のカレンダーの日付と時刻とかtimePickerなんかの時刻もそのままサーバーに渡して、サーバー側でそのままnew Date(<渡された日時>)なんてしても問題は起きません。
(暗黙のうちにタイムゾーン同じなので)

これが以下の場合はどうでしょう?

Web画面(クライアント側)PCのタイムゾーンがAsia/Tokyo(=日本(JST)時間)
バックエンド(サーバー側)サーバーOSに設定されているタイムゾーンがUTC

Web画面では日本時間だと思って「2025/3/11 12:00」と入力したとします。

サーバー側で「2025/3/11 12:00」という文字列を受け取って

const date = new Date("2025/3/11 12:00");

とします。

さて、このdateの中身はどうなっているでしょうか?

日本時間の「2025/3/11 12:00」になっていると期待しますが、UTC時刻の「2025/3/11 12:00」となってしまいます。

つまりdateの中身は「2025-03-11T12:00:00+00:00」(=2025-03-11T12:00:00Z)となっています。

このdateを日本時間に変換をすると「2025-03-11T21:00:00.000Z」(=2025-03-11T21:00:00.000+09:00)となって、日本時間の12:00として処理を始めたつもりが、内部では日本時間21:00として処理されてしまいます。

これが+9時間で日付をまたぐ場合、指定した日付がずれて違う日付のデータを処理してしまう・・・なんてことが起こって、今度は「1日ズレする!!」みたいなことが起こります。

ではどうするのか?

Web画面(クライアント側)からバックエンド(サーバー側)でデータを送信するときには、日付や時刻の文字列を入力されたそのままで渡すのではなく、日時のフォーマット(ISO 8601)にしてから送信します。

{
  "date": "2025/3/11 12:00"
}

ではなく

{
  "date": "2025-3-11T12:00:00+09:00"
}

ですね。

こうすることで、「どのタイムゾーンでの時刻表示なのか?」が情報として含まれるようになるので、クライアントとサーバーでのタイムゾーンが違っていても同じように時刻を扱えます。

サーバー返却するデータフォーマットも同様です。

些細な事ですが、これを明確に決めないでクライアントとサーバー間のデータ通信を実装すると、タイムゾーンの時刻ずれを起こして「クライアントとサーバー側、どっちで直す??」みたいなことが発生、しかも一部はたまたま一致しててうまく動いてて、一部はずれてて・・・・結局影響範囲どこまであるんだ??みたいな非常に厄介な問題に広がったりします(しました・・・)

時刻制御でハマる人が少しでも少なくなることを祈ります・・・

お問い合わせ

サービスに関するご相談やご質問などこちらからお問い合わせください。

03-55107260

受付時間 10:00〜17:00