Fuso horário de análise de data / hora inconsistente em Python

Nov 23 2020

Quando executo o seguinte no Python 3.X

import datetime

DATE_TS_FORMAT = '%Y-%m-%d %H:%M:%S.%f %Z'

date_ts = datetime.datetime(2019, 1, 2, 3, 4, 5, tzinfo=datetime.timezone.utc)
date_ts = date_ts.strftime(DATE_TS_FORMAT)
print(date_ts)
date_ts = datetime.datetime.strptime(date_ts, DATE_TS_FORMAT)
date_ts = date_ts.strftime(DATE_TS_FORMAT)
print(date_ts)

eu recebo

2019-01-02 03:04:05.000000 UTC
2019-01-02 03:04:05.000000 

Por que as informações de fuso horário desapareceram e como posso corrigir esse problema?

Respostas

2 MrFuppes Nov 24 2020 at 07:13

Inconsistente, de fato ... O ponto é que %Zfaz strptime aceitar certas strings (GMT, UTC e qualquer valor em time.tzname - docs ), mas na verdade não faz nada com isso. Ex:

from datetime import datetime

s = "2019-01-02 03:04:05.000000 UTC"
dt = datetime.strptime(s, '%Y-%m-%d %H:%M:%S.%f %Z')

print(repr(dt))
# datetime.datetime(2019, 1, 2, 3, 4, 5)

O objeto datetime resultante é ingênuo; nenhum sinal de UTC mais.

Para explicar esse comportamento, você pode pós-processar o objeto datetime, algo como

if "UTC" in s: 
    dt = dt.replace(tzinfo=timezone.utc)

(o que eu acho um pouco doloroso ...) ou substitua "UTC" por algo que %zanalisa para UTC 1 ,

dt = datetime.strptime(s.replace("UTC", "+00:00"), '%Y-%m-%d %H:%M:%S.%f %z')

print(repr(dt))
# datetime.datetime(2019, 1, 2, 3, 4, 5, tzinfo=datetime.timezone.utc)

(o que eu acho um pouco feio ...) ou use um analisador adequado, por exemplo

from dateutil.parser import parse

dt = parse(s)

print(repr(dt))
# datetime.datetime(2019, 1, 2, 3, 4, 5, tzinfo=tzutc())

print(dt.strftime('%Y-%m-%d %H:%M:%S.%f %Z'))
# 2019-01-02 03:04:05.000000 UTC

(que será um pouco mais lento se o desempenho for um problema ...).


1 IMO, isso também é inconsistente; "+00: 00" também pode ser a diferença UTC de algum fuso horário que por acaso tem uma diferença UTC de 0 horas naquele horário ...