追記(2023/1/11)
TZが予約語ではなくなりましたので、
指定して問題ないです。
はじめに
Lambdaで現在日時を取得する際、
リージョン関係なくデフォルトでUTCとなっています。
そのため業務等では、扱いやすいようにJSTに変換して運用するかと思いますが、
その方法で2022年1月現在、よく見かけるのが2パターン存在します。
本記事はPython3.9を使用していますが、
他の言語に読み替えていただいても内容は問題ありません。
1.Lambdaの環境変数でタイムゾーンを設定する方法
まずは環境変数なしで取得してみます。
from datetime import datetime
def lambda_handler(event, context):
current_at = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(current_at)
実行結果
2022-01-28 11:21:22
この記事の執筆時が20時21分なので、
このようにUTCで取れます。
では次にLambdaの環境変数を設定してみます。
キーにTZ、値にAsia/Tokyoを設定します。
実際に取得してみます。
コードはさっきと同じです。
from datetime import datetime
def lambda_handler(event, context):
current_at = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(current_at)
実行結果
2022-01-28 20:21:59
環境変数の設定だけで、現在日時をJSTで取得できるようになりました。
2.プログラムから取得する際にJSTを指定する方法
環境変数には何も設定しません。
コード上でJSTを指定してから現在日時を取得します。
from datetime import datetime, timedelta, timezone
def lambda_handler(event, context):
JST = timezone(timedelta(hours=+9), 'JST')
current_at = datetime.now(JST).strftime('%Y-%m-%d %H:%M:%S')
print(current_at)
実行結果
2022-01-28 20:22:41
こちらも環境変数のタイムゾーンを変更した場合と同様に、
JSTで取得することが出来ました。
問題点
ここからが本題です。
環境変数の設定で、なぜJSTになるのか…?と疑問を抱き、
気になったので調べてみたところ、
TZがどうやらAWS Lambdaの予約語のようです。
その中に、
予約済み環境変数
TZ - 環境のタイムゾーン (UTC)。実行環境は、システムクロックを同期するために NTP を使用します。
という記述があります。
本当かどうか念のため確認してみると、
import os
def lambda_handler(event, context):
print(os.environ['TZ'])
実行結果
:UTC
確かに設定されています。
さらに、
定義されたランタイム環境変数
Lambda ランタイムは、初期化中にいくつかの環境変数を設定します。ほとんどの環境変数は、関数またはランタイムに関する情報を提供します。これらの環境変数のキーは予約済みであるため、関数設定では設定できません。
環境変数のキーは予約済みであるため、関数設定では設定できませんと書いてありますが、
実際には設定できてしまいます。
結論
仕様なのかどうかは微妙なところですが、
ドキュメントで予約語と明記され、設定もできないとなっているものを設定して使うのは、
基本的によろしくないと思います。
いつ修正されるかも不明ですので、素直にプログラムから取得する際にJSTを指定したほうが良さそうです。
参考
追記(2022/1/31)
@yatsbashy さんより教えて頂きました。
数年前にサーバーワークスさんがAWSサポートに確認されたようです。
AWS のサポートにも確認してみましたが「将来にわたって TZ の上書きが可能であるという保証はできないため環境変数の TZ は使用しないようにお願いします」とのことでした。