概要
Pythonでタイムゾーン付きdatetime(aware)とタイムゾーンなしdatetime(naive)で比較しようとするとエラーになったので解消方法をまとめました。
環境
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.15.6
BuildVersion: 19G2021
$ python3 --version
Python 3.7.3
比較
datetime関数にタイムゾーン情報を渡さずに単純に比較してみると
$ cat sample.py
#!/usr/bin/env python3
from datetime import datetime, timedelta, timezone
def main():
now = datetime.now()
a_day_ago = datetime.now() - timedelta(days=1)
print('success') if now > a_day_ago else print('failure')
if __name__ == '__main__':
main()
問題なく比較できました
$ python3 sample.py
success
ただ、片方にタイムゾーン情報を渡してあげる(aware)と
tz = timezone(timedelta(hours=+9), 'Asia/Tokyo')
now = datetime.now(tz)
a_day_ago = datetime.now() - timedelta(days=1)
print('success') if now > a_day_ago else print('failure')
エラーとなってしまいました。
$ python3 sample.py
Traceback (most recent call last):
File "sample.py", line 23, in <module>
main()
File "sample.py", line 18, in main
print('success') if now > a_day_ago else print('failure')
TypeError: can't compare offset-naive and offset-aware datetimes
Pythonのdatetimeにはタイムゾーン付きのもの(aware)となしのもの(naive)があるようです。
ちなみにタイムゾーン付きの者同士で比較すると
tz = timezone(timedelta(hours=+9), 'Asia/Tokyo')
now = datetime.now(tz)
a_day_ago = datetime.now(tz) - timedelta(days=1)
print('success') if now > a_day_ago else print('failure')
問題なく比較できました。
$ python3 sample.py
success
違うタイムゾーンで試してみても
tz_tokyo = timezone(timedelta(hours=+9), 'Asia/Tokyo')
now = datetime.now(tz_tokyo)
tz_shanghai = timezone(timedelta(hours=+8), 'Asia/Shanghai')
a_day_ago = datetime.now(tz_shanghai) - timedelta(days=1)
print('success') if now > a_day_ago else print('failure')
問題なく比較できました。
$ python3 sample.py
success
datetimeではタイムゾーンの有無を意識していれば比較に困ることはなさそうです。