Python: astimezone (Nenhum) fornece data e hora ciente, não reconhece DST
astimezone(None)é uma maneira conveniente de localizar um objeto datetime para a hora local, ou seja, a configuração do seu sistema operacional ( documentos , exemplo ). No entanto, observei que há uma advertência. Uma vez que estou no CET / CEST e acabamos de ter uma mudança de horário de verão, eu estava brincando com datetime e timedelta ciente. 1
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
t_DSTactive = datetime(2020,10,23, tzinfo=ZoneInfo('Europe/Berlin'))
t_DSTinactive = datetime(2020,10,26, tzinfo=ZoneInfo('Europe/Berlin'))
print(t_DSTinactive - t_DSTactive)
# 3 days, 0:00:00
Como esperado, timedeltamostra a diferença de tempo de parede 2 , que é de 3 dias entre esses horários. Devido à mudança de DST ativo para DST inativo, a duração em UTC é de 3 dias e 1 hora:
t_DSTactive = t_DSTactive.astimezone(timezone.utc)
t_DSTinactive = t_DSTinactive.astimezone(timezone.utc)
print(t_DSTinactive - t_DSTactive)
# 3 days, 1:00:00
Usando asttimezone(None)para localizar, tudo parece estar bem (UTC + 2 → UTC + 1):
DSTinactive = datetime(2020,10,26).astimezone(None)
print(DSTactive, DSTinactive)
# 2020-10-23 00:00:00+02:00 2020-10-26 00:00:00+01:00
... mas timedeltainclui +1 hora da transição do horário de verão:
print(DSTinactive - DSTactive)
# 3 days, 1:00:00
O que está acontecendo aqui?
- 1 Estou usando o MS Windows 10; o resultado pode ser diferente em outras plataformas
- 2 veja também: Semântica da aritmética de data e hora ciente de fuso horário
Respostas
Olhando para os repr()objetos datetime obtidos com .astimezone(None), vemos que o tzinfoatributo é "apenas" a timedeltaem ambos os casos:
print(repr(DSTactive))
print(repr(DSTinactive))
# datetime.datetime(2020, 10, 23, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=7200), 'Mitteleuropäische Sommerzeit'))
# datetime.datetime(2020, 10, 26, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600), 'Mitteleuropäische Zeit'))
Em outras palavras, um deslocamento fixo do UTC , não um fuso horário no sentido geográfico (incluindo as alterações de horário de verão prescritas). Um deslocamento fixo, é claro, não reconhece as alterações do horário de verão. Levando em consideração os deslocamentos, o cálculo está dando corretamente 3 dias, 1 hora de diferença.
Contexto: No src do datetime, vemos queastimezone(None)chamadas_local_timezone()para obter o tzinfo, que retorna isso como um deslocamento fixo.
Embora seja conveniente, astimezone(None)pode levar a resultados inesperados aqui. Uma maneira de contornar esse problema é, obviamente, localizar a data e hora no fuso horário local. O tzlocal pode ser de grande ajuda aqui, especialmente no Windows, que é particularmente relutante em revelar o nome do fuso horário.