datetime, zoneinfo y hora
Almacena instantes en UTC con datetime consciente de la zona horaria. Convierte para mostrar con zoneinfo (tzdata en Windows a través del paquete tzdata). Usa timedelta para duraciones, no solo segundos enteros.
Receta
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())Cuándo usar esto:
- Sellos de tiempo de API (siempre ISO-8601 UTC)
- Formato de visualización local del usuario
- Programación a través de límites de horario de verano (DST)
- Medición del tiempo transcurrido (
monotonicpara rendimiento) - Análisis de cadenas ISO de JSON
Ejemplo funcional
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("se requiere datetime consciente")
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"))Lo que esto demuestra:
- Rechaza datetimes ingenuos en funciones de dominio
- La aritmética con
timedeltapreserva la conciencia de zona horaria - Nombres IANA de
ZoneInfopara DST correcto strftimesolo para visualización: almacena ISO en los datos
Análisis detallado
Consciente vs. Ingenuo
| Tipo | Seguro para |
|---|---|
| Consciente (tz establecido) | Almacenamiento, APIs |
| Ingenuo | Reloj de pared local solo con cuidado |
Medición de rendimiento
time.perf_counter()para benchmarks- No
datetime.nowpara duraciones
Errores comunes
- Comparaciones ingenuas de
now()- Errores de DST. Solución:datetime.now(timezone.utc). - Entero de época en todas partes - Pierde contexto de subsegundo y zona horaria. Solución:
datetimeen modelos, época en el límite si es necesario. zoneinfofaltante en Windows - Instalatzdatade PyPI. Solución: Documentar en el despliegue.- Análisis de horas locales ambiguas - Doblez de DST. Solución: Almacena UTC; convierte solo al mostrar.
strftime %Zengañoso - Las abreviaturas son ambiguas. Solución: Incluye el desplazamiento%zen las APIs.
Alternativas
| Alternativa | Usar cuándo | No usar cuándo |
|---|---|---|
| dateutil | Recurrencia compleja | timedelta simple es suficiente |
| pendulum | Preferencia por API amigable | Política de solo biblioteca estándar |
| entero de época en DB | Esquema heredado | APIs nuevas |
Preguntas frecuentes
¿Almacenamiento UTC obligatorio?
Sí para sistemas distribuidos: convierte en el borde de la UI.
¿`fromisoformat`?
Analiza muchas formas ISO-8601 en 3.11+ - preferir para sellos de tiempo JSON.
¿Cómo probar DST?
Usa datetimes conscientes fijos en las pruebas, no now().
¿`monotonic` vs `time.time`?
perf_counter monotónico para duraciones; time.time (reloj de pared) está sujeto a saltos de NTP.
¿`SQLAlchemy DateTime`?
Almacena consciente de zona horaria o normalizado a UTC: coincide con el tipo de columna de la base de datos.
¿Segundos bisiestos?
Python datetime ignora los segundos bisiestos, igual que la mayoría de los sistemas; usa UTC.
¿Reemplazar `pytz`?
zoneinfo es preferido en código nuevo a partir de 3.9+.
¿Analizar fechas HTTP?
email.utils.parsedate_to_datetime para encabezados RFC 7231.
¿Programar trabajo diario?
Usa un calculador de próxima ejecución consciente o APScheduler: ten cuidado con DST para los desencadenadores de hora local.
¿Pydantic `datetime`?
Convierte cadenas ISO; fuerza la conciencia con validadores en v2.
Relacionado
- json y Serialización - ISO en JSON
- Descripción general de la biblioteca estándar - mapa
- hashlib, secrets y uuid - ids basados en tiempo (precaución con uuid1)
- Mejores prácticas de la biblioteca estándar - reglas de tiempo
Versiones de la pila: Esta página fue escrita para Python 3.14.0 (estable 3.14, mantenimiento 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+ y uv 0.6+.