`datetime.utcnow()` agora está obsoleto
A decisão do Python de descontinuar `datetime.utcnow()` reacendeu tensões antigas sobre como linguagens de programação devem representar o tempo, fusos horários e datetimes “ingênuos” vs. “aware”. Os comentaristas discutem se todos os timestamps devem sempre carregar informação explícita de UTC ou de fuso, como modelar eventos locais vs. globais (como horários de loja ou compromissos em calendário) e se a mudança vale a dor de compatibilidade retroativa e migração para grandes bases de código, especialmente em finanças. Muitos concordam que a API datetime do Python tem sido propensa a erros por anos, mas divergem fortemente sobre se a descontinuação e eventual remoção são uma correção necessária ou uma mudança incompatível desnecessária.
Datetimes ingênuas vs. datetimes com fuso horário
- Muitos concordam que a divisão do Python entre “ingênuo” e “aware” é propensa a erros, especialmente quando se misturam os dois silenciosamente.
- A principal crítica:
utcnow()soa como se retornasse um datetime em UTC com fuso horário, mas na verdade retorna dados ingênuos com semântica local; isso já causou bugs sutis. - Alguns argumentam conceitualmente que “todos os datetimes reais têm um fuso horário” e que datetimes ingênuos deveriam ser raros ou claramente tipos separados.
- Outros insistem que UTC ingênuo é uma convenção interna válida e eficiente, amplamente usada (por exemplo, em finanças), e descontinuá-la é disruptivo.
Casos de uso em que horários locais / ingênuos são necessários
- Eventos recorrentes ou locais: alarmes às “8h local”, compromissos futuros às “10h em Europe/London”, horário de abertura de loja às “9:30h local”, reuniões recorrentes, horários de abertura da bolsa.
- Isso não se mapeia de forma limpa para um único instante UTC, especialmente quando governos mudam regras de horário de verão ou offsets depois do agendamento.
- Alguns querem tipos distintos: timestamps/instantes vs data/hora local vs regras recorrentes, para evitar uso incorreto.
Armazenamento e troca de tempo
- Forte apoio a “armazenar eventos passados em UTC, converter na exibição”; divergência sobre eventos futuros.
- Divergência sobre o melhor armazenamento:
- Inteiros de epoch: simples e rápidos, mas exigem conhecimento implícito de epoch, unidades e UTC; ambíguos sem metadados.
- Strings ISO-8601: autoexplicativas e legíveis por humanos, mas mais lentas e pesadas.
- Tipos de banco de dados: alertas de que “TIMESTAMP WITH TIME ZONE” em alguns bancos só armazena UTC e descarta o fuso original; outros argumentam que ainda é útil.
DST, offsets e fusos horários estranhos
- Participantes listam realidades complicadas: offsets de meia hora e de 45 minutos, offsets históricos incomuns, mudanças políticas frequentes, transições de horário de verão, horas duplicadas.
- Foi apontado que a conversão UTC↔local não é uma função pura estável para datas futuras; você precisa de nomes de zona e bases tz atualizadas.
O que usar no lugar de utcnow e design de API
- Padrão recomendado:
datetime.now(timezone.utc)(ou equivalente), possivelmente removendotzinfoapenas nas fronteiras de serialização. - Alguns gostariam que o Python tivesse tipos separados para datetimes com fuso e sem fuso (como Java, Rust, Elixir) e tivesse tornado “aware” o padrão desde o início.
- Outros argumentam que o Python já tem recursos dinâmicos e mocking, então abstrações pesadas (como o time provider do .NET) são exagero.
Compatibilidade retroativa e impacto no ecossistema
- Há preocupação de que a descontinuação afete grandes bases legadas e financeiras que padronizaram UTC ingênuo.
- Contraponto: descontinuar primeiro e remover depois é mais seguro do que mudar a semântica silenciosamente; análise estática e em tempo de execução podem localizar os pontos de chamada.
- Debate mais amplo sobre a disposição do Python em quebrar APIs na 3.x vs culturas que nunca quebram (C, Java), e se mudanças graduais são melhores do que grandes rupturas no estilo “Python 4”.