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"
}ですね。
こうすることで、「どのタイムゾーンでの時刻表示なのか?」が情報として含まれるようになるので、クライアントとサーバーでのタイムゾーンが違っていても同じように時刻を扱えます。
サーバー返却するデータフォーマットも同様です。
些細な事ですが、これを明確に決めないでクライアントとサーバー間のデータ通信を実装すると、タイムゾーンの時刻ずれを起こして「クライアントとサーバー側、どっちで直す??」みたいなことが発生、しかも一部はたまたま一致しててうまく動いてて、一部はずれてて・・・・結局影響範囲どこまであるんだ??みたいな非常に厄介な問題に広がったりします(しました・・・)
時刻制御でハマる人が少しでも少なくなることを祈ります・・・


