python 3.9.1 tarih-saat aritmetiği

Dec 03 2020

Python3.9.1'de yeni zoneinfo desteğini denerken, datetime duyarlı nesnelerin zaman farklarının pytz tarafından üretilenlerden aşağıdaki programın çıktısında gösterildiği gibi farklı olduğunu fark ettim:

import datetime,zoneinfo,pytz
from sys import version_info
print(f'Python{version_info.major}.{version_info.minor}{version_info.micro}'
f' pytz{pytz.__version__}')
Athens=zoneinfo.ZoneInfo('Europe/Athens')
f='%Y-%m-%d %H:%M:%S'
d=[datetime.datetime.strptime('2020-10-25 00:00:00',f),
   datetime.datetime.strptime('2020-10-25 23:59:59',f)]
print('naive   ',d[1]-d[0])
d=[x.astimezone(Athens) for x in d]
print('zoneinfo',d[1]-d[0])
d=[datetime.datetime.strptime('2020-10-25 00:00:00',f),
   datetime.datetime.strptime('2020-10-25 23:59:59',f)]
athens=pytz.timezone('Europe/Athens')
print('pytz as ',d[1].astimezone(athens)-d[0].astimezone(athens))
print('pytz loc',athens.localize(d[1])-athens.localize(d[0]))

Python3.91 pytz2020.4
naive    23:59:59
zoneinfo 23:59:59
pytz as  1 day, 0:59:59
pytz loc 1 day, 0:59:59

Görünüşe göre yerel saat dilimi destekleri, 2020-10-25'in yaz saatinden kış saatine geçiş günü olduğu ve bu nedenle günün süresinin 25 saat olduğu gerçeğini görmezden geliyor. Neyi kaçırıyorum?

Yanıtlar

MrFuppes Dec 03 2020 at 20:11

Yorumumun bir örneği; ile haberdar datetime tzinfobir zoneinfo ile sette zoneinfodönüşleri bir duvar saati timedelta. Aynısını pytz.timezonebilinçli tarih saat ile yaparsanız, mutlak zaman zaman dilimi elde edersiniz.

from datetime import datetime
from zoneinfo import ZoneInfo
import pytz
from sys import version_info

print(f'Python {version_info.major}.{version_info.minor}{version_info.micro} pytz {pytz.__version__}')
# Python 3.90 pytz 2020.4

d=[datetime.fromisoformat('2020-10-25 00:00:00'), datetime.fromisoformat('2020-10-25 23:59:59')]

Athens = ZoneInfo('Europe/Athens')
print('wall time diff, zoneinfo:', d[1].replace(tzinfo=Athens)-d[0].replace(tzinfo=Athens))
# wall time diff, zoneinfo: 23:59:59

athens = pytz.timezone('Europe/Athens')
print('absolute time diff, pytz:', athens.localize(d[1])-athens.localize(d[0]))
# absolute time diff, pytz: 1 day, 0:59:59

# to get absolute time delta with zoneinfo:
utc = ZoneInfo('UTC')
print('absolute time diff, zoneinfo:', d[1].replace(tzinfo=Athens).astimezone(utc)
                                      -d[0].replace(tzinfo=Athens).astimezone(utc))
# absolute time diff, zoneinfo: 1 day, 0:59:59