環境
$ python --version
Python 2.7.12
タイムゾーンを気にしないとエラーが起こる
TrelloのAPIで取得したカードの時刻と現在の時刻を比較しようとして、以下のコードを書いたらエラーが出てハマった。
def show_cards_(cards):
for c in cards:
print("---------------")
print("card id : {id}".format(id=c.id))
print("card name : {name}".format(name=c.name))
if c.due is not None:
due = c.due_date
now = dt.now()
print("過ぎたよ" if now > due else "まだ大丈夫")
このコードを実行したら、以下のエラーが帰ってきた。
TypeError: can't compare offset-naive and offset-aware datetimes
dueとnowがそれぞれoffset-nativeとoffset-awareで異なるので比較できないらしい。
中身をよく見てみるとこんな感じだった。
2017-01-03 10:00:00+00:00 # dueのほう : offset-aware
2017-01-03 22:40:14.709333 # nowのほう : offset-native
trelloから返ってくるのはoffset-awareのutcの時間だった。
pythonではどっちかに合わせて比較するということらしい。
解決策
ポイント
offset-native
とoffset-aware
を混ぜない。
今までは全然気にしてなかったけど、こういうときにpytz
とpython-dateutil
にお世話になるらしい。
offset-nativeで現時刻を取得する方法
>>> from datetime import datetime as dt
>>> print(dt.now())
2017-01-03 22:45:07.334307+09:00
大体の場合はこれでok
offset-awareで現時刻を取得する方法
>>> from datetime import datetime as dt
>>> import dateutil.tz
>>> print(dt.now(dateutil.tz.tzlocal()))
2017-01-03 22:47:27.712684+09:00
タイムゾーンをAsia/Tokyo
とかに固定することもできるけど、
システムローカルのタイムゾーンをかっこよさそうだったのでそうしてみました。
timezoneの変換(以下はoffset-awareな話)
UTCで時刻取得
>>> from datetime import datetime as dt
>>> import pytz
>>> now_utc = dt.now(pytz.utc)
>>> print(now_utc)
2017-01-03 14:07:54.861061+00:00
いつものdt.now()
にタイムゾーンを変数として渡せばokみたい。
↓そして、
UTC → JST
>>> print(dt.now(pytz.utc).astimezone(pytz.timezone("Asia/Tokyo")))
2017-01-03 23:05:53.765549+09:00
# 以上。
おうちはっく!おうちはっく!
ポルカドットスティングレイとDAOKO最高!