LoginSignup
4
7

More than 3 years have passed since last update.

[Python3]datetimeにタイムゾーンを指定するawareな方法

Last updated at Posted at 2020-01-17

PCでコーディングしたプログラムをAWSのLambda関数で実行したら、datetime.now()で取得される時刻が異なることに気づきました。PCはJST時間、AWSはUTC時間のため9時間の差があることが原因です。
プログラムを変えずにPCでもAWSのLambda関数でも同じ結果を得るために、datetimeにタイムゾーンを指定する方法を調べました。

環境

  • Python 3.7.4

問題の事象

例えば次のプログラムを実行すると、PCで取得される現在時刻と、AWSのLambda関数で取得される現在時刻に9時間の差異が発生します。9時間の差異なので、Lambda関数で実行するときには+ timedelta(hours=+9)として9時間足せばいいのだけれど、それではPCからLambda関数に持っていくときにプログラムの修正が発生するので望ましくないため、プログラムを変更せずに同じ結果が得られるようにしたいと考えました。

lambda_function.py
from datetime import datetime, timezone, timedelta

def lambda_handler(event, context):
    print(datetime.now())
    #PCとAWSのLambda関数で取得される時刻に9時間の差異が発生
    return

if __name__ == "__main__":
    event = None
    context = None
    lambda_handler(event, context)

解決策

datetimeにタイムゾーンを指定することで解決できます。Python3では標準ライブラリのdatetimeだけで解決できます。具体的には、datetimeオブジェクトを生成する際にtimezoneを指定します。
ただし、timezonetimezoneサブクラスから生成する必要があるため、そこでちょっと戸惑いました。
timezone = "Asia/Tokyo"とかではないということです。
「Pythonでは、すべてがオブジェクト」とかたまに見かけますが、こういうことなんですかね。

    JST = timezone(timedelta(hours=+9)) #timezoneの生成
    print(datetime.now(JST)) #タイムゾーンを指定して現在時刻を取得

注意点

datetimeオブジェクトを使った引き算、足し算をしている場合は、タイムゾーンを揃えておかないとTypeErrorが発生します。

TypeError: can't subtract offset-naive and offset-aware datetimes

こんな感じにすればOK

    JST = timezone(timedelta(hours=+9)) #timezoneの生成
    datetime.datetime(2020, 1, 31, tzinfo=JST) - datetime.datetime.now(JST)
    #tzinfoにタイムゾーンを設定

もうひとつの解決策

ここまで調べた後で、もう一つの解決策があることを発見しました。
AWSのLambda関数の環境変数を変更する方法です。いろんなやり方があるのですね。

AWSのLambdaのタイムゾーンをUTCからJST(東京)に変更

なお、

Python3のdatetimeはタイムゾーンを指定するだけで高速になる

そうです。

「awareなdatetime」と「nativeなdatetime」

datetimeを調べる過程で、「awareなdatetime」や「nativeなdatetime」という言葉が出てきて「なんのこっちゃ」と戸惑いましたが、大まかには、

  • datetimeオブジェクトにタイムゾーンを指定する方法は、「awareなdatetime」
  • 実行環境(PC、AWSのLambda関数)のタイムゾーンを合わせる方法は、「nativeなdatetime」

ということみたいです。

言葉だけだと少々理解しにくいですが、実際にプログラムを動かしてみて結果の差異を見ることで実感できました。

4
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
4
7