Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Pythonのdatetimeモジュールを使った時に、タイムゾーンを固定させる方法

More than 1 year has passed since last update.

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オブジェクトを扱うときは、どっちかにそろえたほうが良いってことだね。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away