なにが問題か
はじめに、Firebase FunctionsのデフォルトTimezoneは UTC です。
console.log(process.env.TZ);
// -> undefined
これはタイムスタンプとの比較などを行う分には問題有りませんが、日付や時刻を操作しようとするととたんに問題になります。
例えば1日の開始時間を取得したい場合、日本時間で考えているとズレが生じます。
import { startOfDay } from 'date-fns';
const now = new Date();
// -> 2022-01-26T23:00:00.000Z (日本時間では 2022-01-27 08:00:00)
console.log(startOfDay(now));
// -> 2022-01-26T00:00:00.000Z (日本時間では 2022-01-26 09:00:00)
本来は日本時間での 2022-01-27 00:00:00 が取得したいのに、2022-01-26 09:00:00 になってしまう
上手く動かない対応
regionやscheduleのtimezoneを指定してもTimezoneは変わりません
// どちらもTimezoneには影響しない
functions
.region('asia-northeast1')
.https
.onRequest(async (req, res) => {
});
functions
.region('asia-northeast1')
.pubsub.schedule('* * * * *')
.timeZone('Asia/Tokyo')
.onRun(async () => {
})
Timezoneを変更する
Functionのランタイム環境変数にTZを追加することで変更します。
GCPコンソールからの変更
Google Cloud PlatformのCloud Functionから目的の関数の詳細に入り、編集リンクを開きます。
ランタイム環境変数の設定項目があるので、以下を追加しデプロイします。
- 名前:
TZ
- 値:
Asia/Tokyo
ただ関数一つ一つの設定が必要なので面倒です。
可能であればコードベースで管理したい。
GCloudコマンドでデプロイ
gcloudコマンドで関数をデプロイする場合、環境変数を渡せるようです。
$ gcloud functions deploy "secretDemo" \
--runtime "nodejs14" \
--trigger-http \
--allow-unauthenticated \
--set-env-vars "TOKEN=abcd1234"
こちらもデプロイ毎に指定が必要なので面倒です。
やっぱり可能であればコードベースで管理したい。
Functionsのコードから変更
process.env.TZ = "Asia/Tokyo";
export const checkTimezone = functions.region('asia-northeast1').https.onRequest(async (req, res) => {
console.info(process.env.TZ)
// -> Asia/Tokyo
});
コレが一番いいかもしれない。
変更した結果
すると先程の実行結果が変わってくるはずです。
import { startOfDay } from 'date-fns';
console.log(process.env.TZ);
// -> Asia/Tokyo
const now = new Date();
// -> 2022-01-26T23:00:00.000Z (日本時間では 2022-01-27 08:00:00)
console.log(startOfDay(now));
// -> 2022-01-26T15:00:00.000Z (日本時間では 2022-01-27 00:00:00)