LoginSignup
7
4

More than 5 years have passed since last update.

pythonでシステムローカルのタイムゾーンで現時刻を取得する、そして変換する

Posted at

環境

$ 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-nativeoffset-awareを混ぜない。

今までは全然気にしてなかったけど、こういうときにpytzpython-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最高!

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