見出し画像

Vercel環境でSSRしたときタイムゾーンがズレる場合の対処方法

どうも。
Vercelサーバーとローカルのタイムゾーンのズレによる問題で苦労したポイントがありましたので、その内容を共有したいと思います。


1.結論

● ローカルで開発している場合、SSRの処理はAsia/Tokyoのタイムゾーンで行われます。
● Vercelにデプロイした場合、SSRの処理はUTCタイムゾーンで行われます。

以上のことから、VercelでSSRする場合には9時間のタイムゾーンの差が生じます。
その結果、Vercelにデプロイされた場合、プログラム内で12:00を判定している箇所などがズレる可能性があります。

2.今回の要件

● Next.jsで開発を行い、Vercelにデプロイします。
● SEO対策のために、getServerSidePropsを使用してサーバーサイドレンダリング(SSR)を行います。
● ECサイトの仕様上、特定の時間帯にのみ在庫が制限されているため、ページの描画時にお昼の12:00前後かどうかを判定し、商品の購入可否を制御します。
● 時間の管理にはdayjsライブラリを使用します。

という要件に基づいて、上記の機能を実装しました。

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の判定

ここで困ったことが発生しました。

僕「あれ、、、今日のお昼の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サーバーとローカル環境で時間がズレるとは思っていなかったので、想定外のバグを仕込むことになってしまいましたが、今後気をつけて実装できればと思います。

参考になれば幸いです。では今回はこれまで。

この記事が気に入ったらサポートをしてみませんか?