datetime, zoneinfo & time
Armazene instantes em UTC com datetime ciente de fuso horário. Converta para exibição com zoneinfo (tzdata no Windows via pacote tzdata). Use timedelta para durações, não apenas segundos inteiros.
Receita
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
utc_now = datetime.now(timezone.utc)
local = utc_now.astimezone(ZoneInfo("America/New_York"))
print(utc_now.isoformat(), local.isoformat())Quando usar:
- Carimbos de data/hora de API (sempre UTC ISO-8601)
- Formatação de exibição local para o usuário
- Agendamento entre limites de horário de verão (DST)
- Medição de tempo decorrido (
monotonicpara desempenho) - Análise de strings ISO de JSON
Exemplo de Trabalho
from datetime import datetime, timedelta, timezone
from zoneinfo import ZoneInfo
def next_billing(from_utc: datetime, days: int) -> datetime:
if from_utc.tzinfo is None:
raise ValueError("datetime ciente é obrigatório")
return from_utc + timedelta(days=days)
def format_for_user(instant_utc: datetime, tz_name: str) -> str:
tz = ZoneInfo(tz_name)
return instant_utc.astimezone(tz).strftime("%Y-%m-%d %H:%M %Z")
start = datetime(2026, 7, 9, 12, 0, tzinfo=timezone.utc)
due = next_billing(start, 30)
print(format_for_user(due, "Europe/Berlin"))O que isso demonstra:
- Rejeitar datetimes ingênuos em funções de domínio
- A aritmética com
timedeltapreserva a consciência do fuso horário - Nomes IANA do
ZoneInfopara DST correto strftimeapenas para exibição - armazene ISO em dados
Mergulho Profundo
Ciente vs. Ingênuo
| Tipo | Seguro para |
|---|---|
| Ciente (tz definido) | Armazenamento, APIs |
| Ingênuo | Relógio local apenas com cuidado |
Cronometragem de Desempenho
time.perf_counter()para benchmarks- Não
datetime.nowpara durações
Armadilhas
- Comparações
now()ingênuas - Bugs de DST. Correção:datetime.now(timezone.utc). - Inteiro de época em tudo - Perde subsegundos e contexto de tz. Correção: datetime em modelos, época na fronteira, se necessário.
zoneinfoausente no Windows - instaletzdataPyPI. Correção: documentar na implantação.- Análise de horários locais ambíguos - Dobra de DST. Correção: armazene UTC; converta apenas na exibição.
strftime %Zenganoso - abreviações ambíguas. Correção: inclua o deslocamento%znas APIs.
Alternativas
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
| dateutil | Recorrência complexa | timedelta simples é suficiente |
| pendulum | Preferência por API amigável | Política de apenas biblioteca padrão |
| inteiro de época em DB | Esquema legado | APIs novas |
FAQs
Armazenamento UTC é obrigatório?
Sim para sistemas distribuídos - converta na borda da UI.
fromisoformat?
Analisa muitas formas ISO-8601 em 3.11+ - prefira para timestamps JSON.
Como testar DST?
Use datetimes cientes fixos em testes - não now().
monotonic vs time.time?
perf_counter é monotônico para durações; time.time é relógio de parede sujeito a saltos NTP.
SQLAlchemy DateTime?
Armazene ciente de fuso horário ou normalizado em UTC - corresponda ao tipo de coluna do DB.
Segundos bissextos?
O datetime do Python ignora segundos bissextos - o mesmo que a maioria dos sistemas; use UTC.
Substituir pytz?
zoneinfo é preferido em código novo a partir do 3.9+.
Analisar datas HTTP?
email.utils.parsedate_to_datetime para cabeçalhos RFC 7231.
Agendar trabalho diário?
Use um calculador de próxima execução ciente ou APScheduler - observe o DST para gatilhos de horário local.
Pydantic datetime?
Coerge strings ISO; imponha a consciência com validadores na v2.
Relacionados
- json & Serialização - ISO em JSON
- Visão Geral da Biblioteca Padrão - mapa
- hashlib, secrets & uuid - IDs baseados em tempo (cuidado com uuid1)
- Melhores Práticas da Biblioteca Padrão - regras de tempo
Versões de Stack: Esta página foi escrita para Python 3.14.0 (estável 3.14, manutenção 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, e uv 0.6+.