Vercel環境でSSRしたときタイムゾーンがズレる場合の対処方法
どうも。
Vercelサーバーとローカルのタイムゾーンのズレによる問題で苦労したポイントがありましたので、その内容を共有したいと思います。
1.結論
以上のことから、VercelでSSRする場合には9時間のタイムゾーンの差が生じます。
その結果、Vercelにデプロイされた場合、プログラム内で12:00を判定している箇所などがズレる可能性があります。
2.今回の要件
という要件に基づいて、上記の機能を実装しました。
3.実装の中身
import dayjs from 'dayjs';
import timezone from 'dayjs/plugin/timezone';
import utc from 'dayjs/plugin/utc';
//-----------------------------------------------------------------
// class
//-----------------------------------------------------------------
export class Days {
//-----------------------------------------------------------------
// constructor
//-----------------------------------------------------------------
constructor() {
dayjs.extend(timezone);
dayjs.extend(utc);
dayjs.tz.setDefault('Asia/Tokyo');
}
//-----------------------------------------------------------------
// 時間が商品購入可能時間かどうかを判定する
//-----------------------------------------------------------------
public isAvailableBuyLimit = (limitTime: string): boolean => {
// 当日の日付をtzで取得
const today = dayjs().tz().format('YYYY-MM-DD');
// 当日の12:00と現在の時刻を比較
const isBeforeLimit = dayjs().tz().isBefore(`${today}T${limitTime}+09:00`);
// 12:00前だったらTrue、12:00を過ぎていたらfalseを返す
return isBeforeLimit;
};
}
まず、タイムゾーンをUTCからAsia/Tokyoに設定します。
これにより、Vercel上のアプリケーションではUTCおよびAsia/Tokyoの時間で処理されることになります。
以下のコードでは、クラスの初期化を行い、関数に引数として12:00:00を渡しています。
const day = new Day();
day.isAvailableBuyLimit('12:00:00');
4.お昼の12:00の判定
ここで困ったことが発生しました。
dayjsのドキュメントなどを見ても意外と書き方がよくわからなかったのですが、以下が正解です。
const todaysNoon = `${dayjs().tz().format('YYYY-MM-DD')}T${limitTime}+09:00`;
通常のUTCのフォーマットに12:00:00を入れるだけでした。
これで当日のお昼の12:00を設定できるようになり、現在の時間と当日のお昼の12:00をUTCで比較できるようになりました。
まさかVercelサーバーとローカル環境で時間がズレるとは思っていなかったので、想定外のバグを仕込むことになってしまいましたが、今後気をつけて実装できればと思います。
参考になれば幸いです。では今回はこれまで。