Wiki Python para dados
Datas, horas e fusos
Timestamp sem fuso é ambíguo. Guarde em UTC, converta na hora de mostrar, e cuidado com a diferença entre data e instante.
Um datetime pode ser "ingênuo" (sem fuso) ou "consciente" (com fuso). Comparar os dois tipos dá erro, e isso é bom: misturar os dois é bug.
from datetime import datetime, timedelta, timezone
brasilia = timezone(timedelta(hours=-3))
evento = datetime(2024, 6, 1, 23, 30, tzinfo=brasilia)
print(evento.isoformat())
print(evento.astimezone(timezone.utc).isoformat())
print(evento.date(), evento.astimezone(timezone.utc).date())Saída (conferida)
2024-06-01T23:30:00-03:00 2024-06-02T02:30:00+00:00 2024-06-01 2024-06-02
O mesmo instante cai em dias diferentes conforme o fuso. Relatório "de vendas do dia" precisa dizer de qual fuso é o dia.
Epoch
Sistemas trocam instantes como segundos (ou milissegundos) desde 1970-01-01 UTC.
from datetime import datetime, timezone
segundos = 1717286400
print(datetime.fromtimestamp(segundos, tz=timezone.utc).isoformat())
print(int(datetime(2024, 6, 2, tzinfo=timezone.utc).timestamp() * 1000))Saída (conferida)
2024-06-02T00:00:00+00:00 1717286400000
Ler e formatar
from datetime import datetime
d = datetime.strptime("05/06/2024 14:07", "%d/%m/%Y %H:%M")
print(d.strftime("%Y-%m-%d %H:%M:%S"))
print(d.weekday(), d.strftime("%j"))Saída (conferida)
2024-06-05 14:07:00 2 157
weekday() conta segunda-feira como 0: 2 é quarta-feira. %j é o dia do ano.
- Para fusos com horário de verão use
zoneinfo.ZoneInfo("America/Sao_Paulo")(PEP 615), que lê a base de fusos do sistema. O Brasil não tem horário de verão desde 2019, mas dado antigo tem. - No Spark,
spark.sql.session.timeZonedecide comotimestampé mostrado e convertido: fixe essa configuração no job, em vez de herdar a da máquina.
Fontes
Conhecimento compartilhado pela Genesis Innovation.