TL;DR
タイムゾーンに関するインスタンスを引数としてかませるといいよ。
サーバーがどこにあろうと同じ時間を指してくれる。
import datetime
JST = datetime.timezone(datetime.timedelta(hours=9), "JST")
print(f"ただいま、世界協定時刻で {datetime.datetime.now(datetime.timezone.utc)} です")
# ただいま、世界協定時刻で 2018-12-31 14:03:05.436561+00:00 です
print(f"ただいま、日本時刻で {datetime.datetime.now(JST)} です")
# ただいま、日本時刻で 2018-12-31 23:03:05.436561+09:00 です
悩む
個人的にwebアプリケーションを作成したけれど、費用をできるだけ抑えるためにデプロイ先をIBM BlueMixにした。
時刻を使用して、一定時刻になったら動作する…といったプログラムを書いたのだけれど、サーバーがアメリカにあるせいで、設定した時刻の9時間後に動作してしまう。
この対処法として、datetime
オブジェクトにtimezone
を与えてあげるといいということを思い出した。
つまり
datetime.timezone
インスタンスを作成して、それをdatetime
オブジェクトの引数tzinfo
として与える
日本は世界協定時刻から見て9時間進んでいるので、9時間進んでいる設定にしてあげる
import datetime
JST = datetime.timezone(datetime.timedelta(hours=9), "JST")
第一引数には世界協定時刻からの時間差を示す-datetime.timedelta(hours=24)
からdatetime.timedelta(hours=24)
の間のdatetime.timedelta
オブジェクトを与え、第二引数には名前を与える。
それを以下の様にdatetime.datetime
に与えてやる
certain_time = datetime.datetime(2020, 0, 0, tzinfo=JST) # キーワード引数として与えるときは tzinfo
now = datetime.datetime.now(JST)
こうすると、イイ感じで日本の時間になってくれます。
更になんと、アメリカとか(世界協定時刻-7とか)にするとサマータイムの対応まで自動でやってくれます。wow
timestampから日本時刻に直すには
stamp = datetime.datetime.now(JST).timestamp()
stamp
# 1546266904.187328
datetime.datetime.fromtimestamp(stamp, tz=JST)
# datetime.datetime(2018, 12, 31, 23, 35, 4, 187328, tzinfo=datetime.timezone(datetime.timedelta(0, 32400), 'JST'))
といった感じで、tz
としてdatetime.timezone
インスタンスを与えてあげます。
注意点
タイムゾーンに関する情報を与えたdatetime.datetime
オブジェクトはaware
、そうでないものはnaive
と呼ばれ、互いの比較、演算ができません。
datetime.datetime(2019, 1, 1) - datetime.datetime.now()
# datetime.timedelta(0, 1225, 880213)
datetime.datetime(2019, 1, 1) - datetime.datetime.now(JST)
# ---------------------------------------------------------------------------
# TypeError Traceback (most recent call last)
# <ipython-input-35-33a1ced3b530> in <module>()
# ----> 1 datetime.datetime(2019, 1, 1) - datetime.datetime.now(JST)
# TypeError: can't subtract offset-naive and offset-aware datetimes
datetime.datetime(2019, 1, 1) > datetime.datetime.now(JST)
# ---------------------------------------------------------------------------
# TypeError Traceback (most recent call last)
# <ipython-input-36-3121cc180bc8> in <module>()
# ----> 1 datetime.datetime(2019, 1, 1) > datetime.datetime.now(JST)
# TypeError: can't compare offset-naive and offset-aware datetimes
つまり、一つのプロジェクトの中で複数のdatetime.datetime
オブジェクトを扱うときは、どっちかにそろえたほうが良いってことだね。