aritmética datetime python 3.9.1

Dec 03 2020

Ao tentar o novo suporte zoneinfo em python3.9.1, notei que as diferenças de tempo de objetos com reconhecimento de data e hora diferem daqueles produzidos por pytz, conforme mostrado pela saída do programa abaixo:

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

Parece que o suporte de fuso horário nativo ignora o fato de que 2020-10-25 foi o dia da mudança do horário de verão para o inverno e, portanto, a duração desse dia foi de 25 horas. o que estou perdendo?

Respostas

MrFuppes Dec 03 2020 at 20:11

Uma ilustração do meu comentário; ciente datetime com tzinfodefinido com um ZoneInfo de zoneinforetorna um tempo de parede timedelta. Se você fizer o mesmo com a pytz.timezonedata e hora ciente, obterá o tempo absoluto timedelta.

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