LoginSignup
7
7

More than 3 years have passed since last update.

Lambda(node.js)とJavaScriptのタイムゾーン

Last updated at Posted at 2020-07-29

Lambda(node.js)で日付の計算をしたら思ったより面倒だったのでまとめる。

やりたかったこと

日本標準時(JST)で先週/先月の範囲を、世界標準時(UTC)で取得したい。
例えば、今日が 2020-07-29 とすると先週の範囲は日曜日始まりでこんな感じ。

タイムゾーン 開始 終了
JST 2020-07-19T00:00:00+0900 2020-07-26T00:00:00+0900
UTC 2020-07-18T15:00:00Z 2020-07-25T15:00:00Z

やりたくなかったこと

大した処理じゃないので余計なライブラリは使いたくない。

結論

  • タイムゾーンの設定はそのままにプログラム内で対応する
  • タイムゾーンオフセット値からJSTを自力で設定する
  • UTCへの変換も自力でやる

それぞれのタイムゾーン

Lambdaのタイムゾーン

UTCに固定されている模様。

ググるとTZ環境変数を設定すればいいという記事が大量にヒットする。
ただ、TZ環境変数はAWSに予約されているので、それを変更するのはよろしくなさそう。
Lambda のタイムゾーンを環境変数TZで指定してはいけないっていう話 | Serverworks ENGINEER BLOG

他の利用しているAWSサービスでUTCで動作するものもあったので、プログラム内で対応することにした。

JavaScriptのタイムゾーン

JavaScriptのDateクラスにはタイムゾーンを設定する方法はないようだった。
ただ getTimezoneOffset で分単位の時差は取得できた。JSTは+9時間なので、なぜか-540分が返ってくる。取得した値を+しとけばUTCに変更できそう。

toLocaleString でタイムゾーン指定の日付文字列を取得して、新しくDateオブジェクトを作る方法もあるようだが、Lambdaでは動作しないのとDateクラスのコンストラクタに日付文字列を渡すのは非推奨だったのでやめた。

最終的にJavaScriptのタイムゾーンは無視して getTimezoneOffset を使って自力で日時を計算することにした。

オレのMacのタイムゾーン

JSTだった。
AWS SAMを使ってローカルで開発していると、ローカルではJSTでLambda上ではUTCになる。
タイムゾーンを変更してテストしたい場合は、TZ環境変数を設定することで変更できる。

実装

日本標準時で現在日時を取得

考慮するタイムゾーンはJSTかUTCの2つという前提で、タイムゾーン設定を無視して日本標準時での現在日時を取得することにした。

const jstOffset = 9 * 60;
const now = new Date();
const offset = now.getTimezoneOffset() + jstOffset;
now.setTime(date.getTime() + offset * 60 * 1000);

先週の開始/終了日時を取得

日本標準時で先週の日曜日を取得。

const start = new Date(now.getFullYear(), now.getMonth(), now.getDate());
start.setDate(start.getDate() - 7 - start.getDay());

同様に今週の日曜日を取得。

const end = new Date(now.getFullYear(), now.getMonth(), now.getDate());
end.setDate(end.getDate() - end.getDay());

先月の開始/終了日時を取得

先月1日を取得。

const start = new Date(now.getFullYear(), now.getMonth() - 1, 1);

今月1日を取得。

const end = new Date(now.getFullYear(), now.getMonth(), 1);

JST→UTCの変換

それぞれの日付をUTCに変換。
実際はタイムゾーンを変換してないので getUTCFULLYear などは使えない。

const jstOffset = 9 * 60;
date.setTime(date.getTime() - jstOffset * 60 * 1000);

date.getFullYear();
date.getMonth() + 1;
date.getDate();
date.getHours();
7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7