⚱️

Lambda(Python3.9)でzoneinfoを使ってタイムゾーン設定するとかんたん

2022/10/15に公開

LambdaのタイムゾーンはデフォルトではUTCなのですが、JSTのつもりで気づかず失敗したことがあります。変更も少し手間だったのですが、Python3.9以降はzoneinfoでいいのでは、という話。

Python3.8まで

こんな感じで変えても良いみたいですが(実際変えられる)・・・

os.putenv('TZ', 'Asia/Tokyo')
time.tzset()
print(datetime.datetime.now())

環境変数TZを使うのが、あまりよろしくなさそう。

え、変更できているけど? と思ってしまうのですが、予約済みと AWS が言っている以上、ここを書き換えるという実装はバッドノウハウです。
AWS のサポートにも確認してみましたが「将来にわたって TZ の上書きが可能であるという保証はできないため環境変数の TZ は使用しないようにお願いします」とのことでした。

https://blog.serverworks.co.jp/tech/2019/10/30/lambda-timezone-2/

それでどうするかというと、紹介されているのはpytzモジュールを使う方法で、Lambdaにわざわざ同梱しないといけないので、ちょっと手間ですね。。

https://blog.serverworks.co.jp/tech/2019/06/03/lambda-timezone/

zoneinfoモジュール

Python3.9で追加されたzoneinfoを使うと、かんたんそうです。Lambda(python3.9)には標準で用意されていますので、特別なアップロードなども不要です。

from datetime import datetime
from zoneinfo import ZoneInfo

tokyo = ZoneInfo("Asia/Tokyo") # タイムゾーン情報を取得

now = datetime(2020, 10, 1, 0, 0, 0, tzinfo=tokyo) # Asia/Tokyoタイムゾーンでの現在時刻を取得
print(now.isoformat())

https://www.python.jp/pages/python3.9.html#zoneinfoモジュール

nowには直接tokyoを入れればよよいです。

>>> datetime.now()
datetime.datetime(2022, 10, 15, 14, 28, 42, 669649)

>>> datetime.now(tokyo)
datetime.datetime(2022, 10, 15, 14, 28, 45, 440716, tzinfo=zoneinfo.ZoneInfo(key='Asia/Tokyo'))

# 2020-10-01T00:00:00+09:00

todayには何も入らないのでLambdaではUTCのみになりそう。

>>> datetime.today()
datetime.datetime(2022, 10, 15, 14, 29, 2, 314646)

>>> datetime.today(tokyo)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: datetime.today() takes no arguments (1 given)

Timezoneの変更

astimezoneを使います。

dt = datetime.datetime(2022, 10, 15, 14, 29, 2, 314646)

LOS_ANGELES = ZoneInfo("America/Los_Angeles")

dt.astimezone(LOS_ANGELES)
# datetime.datetime(2022, 10, 14, 22, 29, 2, 314646, tzinfo=zoneinfo.ZoneInfo(key='America/Los_Angeles'))

参考になります↓

https://zenn.dev/fujimotoshinji/scraps/f9c25aeb00a716

まとめ

Python3.9以降のLambdaでは、標準モジュールのzoneinfoを使ってタイムゾーン変換ができます

Discussion