Lambda のタイムゾーンを環境変数TZで指定してはいけないっていう話 (追記あり)

記事タイトルとURLをコピーする

[追記]
ドキュメントが更新され、環境変数のTZは「予約済み環境変数」から「予約されていない環境変数」に変更になっています。

現在は、環境変数TZを指定してタイムゾーンを更新しても問題なくなったようです。

docs.aws.amazon.com


技術1課の加藤です。
今回はプログラムを書いたことがある人なら誰もが一度は悩む「タイムゾーン 」のお話。
Lambda の環境変数 TZ は使っちゃいけないよ。

プログラムのタイムゾーンをどう統一するのか問題

時刻を扱うプログラムを書くとき、避けて通れない敵がタイムゾーン 。
世界には時差というものが存在しますから、時刻を扱う際にはそれを意識した設計にしなければなりません。

AWSでは、基本的に、タイムゾーン はUTC(協定世界時)がデフォルトです。ですので日本で扱う場合にはこれをどこかでJSTに変換してやる必要があります。やり方はいくつかあるのですが、大きく分けると2つ。

  1. プログラム内で、タイムゾーンを明示的に変換する
  2. プログラムの実行環境のタイムゾーンを指定する

1はプログラム内に出てくる時刻のタイムゾーンを都度指定していく方法です。時刻を扱う際に都度タイムゾーンを意識する必要が出てくるため抜け漏れの可能性やプログラムの複雑化といった問題がありえますが、JSTで受け取った時刻をUTCでデータベースに保存する、といった細かな制御が可能になります。

一方後者は、プログラムを実行する環境のタイムゾーンを指定することで、プログラム内では特にタイムゾーンを意識しないようにする方法です。特定のタイムゾーン しか使わないようなプログラムの場合には、そもそも実行環境のタイムゾーンを指定しそちらに合わせてしまう方が楽ですよね。

Lambda のタイムゾーンを指定したいなら TZ を使えばいい…?

さてここから Lambda で実行するプログラムを考えてみましょう。
細かな制御をしたければもちろんプログラム内で指定する方法一択なのですが、大抵の場合、タイムゾーンは一意である方が楽です。そう考えて 「Lambda タイムゾーン」などと検索すると「環境変数の TZ にタイムゾーンを指定することでタイムゾーン を固定することが可能」という記述が見つかります。

確かに AWS の公式ドキュメント Lambda 関数で使用できる環境変数を見ると、タイムゾーン の指定に TZ を使っているという記述があります。また 2019/10/30現在、環境変数TZにタイムゾーンを指定することで想定どおり変更できることも確認できます。

お、簡単やんけ、と思ってしまうのですが、

実はこれ、 非推奨 です。

TZ は AWS が予約している環境変数

先ほど挙げたリンクを再度見ていただきたいのですが、表の TZ の行の リザーブド が あり となっています。
わかりにくいのですが、要するにこれは「TZという環境変数は AWS 側で設定しているもの(=予約済み)だから変更できませんよ」という意味になります。

え、変更できているけど? と思ってしまうのですが、予約済みと AWS が言っている以上、ここを書き換えるという実装はバッドノウハウです。

AWS のサポートにも確認してみましたが「将来にわたって TZ の上書きが可能であるという保証はできないため環境変数の TZ は使用しないようにお願いします」とのことでした。

というわけで、 Lambda のタイムゾーン指定のために環境変数 TZ を変更する はバッドノウハウです。覚えておきましょう。

じゃあどうしたらいいんだ…!

というあなたにはこちらの記事を。
AWS Lambda でのタイムゾーン変換 – サーバーワークスエンジニアブログ

面倒かもしれませんが、プログラム側で正しく指定してあげましょう。