みんなの
2022/04/14 Ryuji Tsutsui
Ryuji Tsutsui @ryu22e
普段は
関わっている
PyCon APAC 2013、
zoneinfoの
zoneinfoの
zoneinfoの
IANA
Internet Assigned Numbers Authority(IANA)が
この
2019年5月15日の
「IANA
かくして、
zoneinfo登場以前には、
zoneinfo: OSに
pytz:
zoneinfo: Python 3.6から
pytz:
ZoneInfoクラスの
ZoneInfoクラスを
>>> from zoneinfo import ZoneInfo
>>> ASIA_TOKYO = ZoneInfo('Asia/Tokyo')
>>> ASIA_TOKYO
zoneinfo.ZoneInfo(key='Asia/Tokyo')
>>> from zoneinfo import ZoneInfo
>>> # オブジェクトはタイムゾーン名ごとにキャッシュされる
>>> ZoneInfo('Asia/Tokyo') is ZoneInfo('Asia/Tokyo')
True
>>> ZoneInfo('America/Los_Angeles') is \
... ZoneInfo('America/Los_Angeles')
True
>>> ZoneInfo('America/Los_Angeles') is \
... ZoneInfo('Asia/Tokyo')
False
>>> import zoneinfo
>>> # 指定できる値はzoneinfo.available_timezones()で調べられる
>>> zoneinfo.available_timezones() # set型の値が返ってくる
{'Asia/Seoul', (省略), 'Asia/Tokyo', (省略), 'Asia/Pyongyang'}
>>> from zoneinfo import ZoneInfo
>>> ZoneInfo('spam')
Traceback (most recent call last):
(省略)
zoneinfo._common.ZoneInfoNotFoundError: 'No time zone found with key spam'
>>> from zoneinfo import ZoneInfo
>>> from datetime import datetime
>>> ASIA_TOKYO = ZoneInfo('Asia/Tokyo')
>>> # 日本時刻で2021年2月23日10:00のdatetimeオブジェクトを作成
>>> dt = datetime(2021, 2, 23, 10, tzinfo=ASIA_TOKYO)
>>> dt
datetime.datetime(2021, 2, 23, 10, 0, tzinfo=zoneinfo.ZoneInfo(key='Asia/Tokyo'))
>>> # (前のスライドのコードの続き)
>>> # 日本時刻2021年2月23日10:00をアメリカのロサンゼルスの日時に変換
>>> dt.astimezone(ZoneInfo('America/Los_Angeles'))
datetime.datetime(2021, 2, 22, 17, 0, tzinfo=zoneinfo.ZoneInfo(key='America/Los_Angeles'))
続いて、
…が、
公式ドキュメント
https://docs.python.org/ja/3/library/datetime.html#datetime.datetime.fold
[0, 1] の
https://docs.python.org/ja/3/library/datetime.html#datetime.datetime.fold
[0, 1] の
>>> from zoneinfo import ZoneInfo
>>> from datetime import datetime
>>> # アメリカ ロサンゼルスの2020-11-01 1:00
>>> dt = datetime(2020, 11, 1, 1, tzinfo=ZoneInfo('America/Los_Angeles'))
>>> print(dt) # 標準時間(UTC+8:00)? それとも夏時間(UTC+7:00)?
夏時間の
すると、
datetimeオブジェクトの
0なら
>>> from zoneinfo import ZoneInfo
>>> from datetime import datetime
>>> dt = datetime(2020, 11, 1, 1, tzinfo=ZoneInfo('America/Los_Angeles'))
>>> print(dt) # デフォルトはfold=0、つまり夏時間(UTC+7:00)
2020-11-01 01:00:00-07:00
>>> print(dt.replace(fold=1)) # fold=1の時は標準時間(UTC+8:00)
2020-11-01 01:00:00-08:00
>>> from pytz import timezone
>>> from datetime import datetime
>>> LOS_ANGELES = timezone('America/Los_Angeles')
>>> dt = LOS_ANGELES.localize(datetime(2020, 11, 1, 1))
>> # fold=0の時は遷移前のオフセット
>>> print(dt)
2020-11-01 01:00:00-08:00
>> # fold=0の時と結果が変わっていない
>>> print(dt.replace(fold=1))
2020-11-01 01:00:00-08:00
実は、
例えば、
Dai MIKURUBEさんの
https://zenn.dev/dmikurube/articles/curse-of-timezones-common-ja
今年の
https://www.newsweekjapan.jp/headlines/world/2022/03/377243.php
アメリカも
>>> from zoneinfo import ZoneInfo
>>> ASIA_TOKYO = ZoneInfo('Asia/Tokyo') # Asia/Tokyoは存在するはずなのに…
Traceback (most recent call last):
(省略)
ModuleNotFoundError: No module named 'tzdata'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "", line 1, in
File "C:\Users\****\AppData\Local\Programs\Python\Python39\lib\zoneinfo\_common.py", line 24, in load_tzdata
raise ZoneInfoNotFoundError(f"No time zone found with key {key}")
zoneinfo._common.ZoneInfoNotFoundError: 'No time zone found with key Asia/Tokyo'
tzdataと
$ pip install tzdata
zoneinfoで
と
Windowsでは
詳細は
>>> from dateutil.tz import gettz
>>> from datetime import datetime
>>> dt = datetime(2020, 11, 1, 1, tzinfo=gettz('America/Los_Angeles'))
>>> print(dt) # fold=0の時は遷移前のオフセット
2020-11-01 01:00:00-07:00
>>> print(dt.replace(fold=1)) # fold=1の時は遷移後のオフセット
2020-11-01 01:00:00-08:00
Djangoは
元々は
Django 3.2からは
Django 4.0(2022/04/14時点での
>>> from zoneinfo import ZoneInfo
>>> from django.utils import timezone
>>> # timezoneという引数がある関数にZoneInfoオブジェクトを渡します。
>>> timezone.localtime(timezone=ZoneInfo('Asia/Tokyo'))
datetime.datetime(2021, 9, 7, 22, 12, 43, 952260, tzinfo=zoneinfo.ZoneInfo(key='Asia/Tokyo'))
zoneinfoは
zoneinfoは
fold属性とは、
Windowsで
質問あればどうぞ!