`datetime.utcnow()` ahora está obsoleto
La decisión de Python de deprecar `datetime.utcnow()` ha reavivado tensiones de larga data sobre cómo los lenguajes de programación deben representar el tiempo, las zonas horarias y los datetimes “ingenuos” frente a los “conscientes”. Los comentaristas debaten si todas las marcas temporales deben llevar siempre información explícita de UTC o de zona, cómo modelar eventos locales frente a globales (como horarios de tiendas o citas de calendario), y si el cambio merece el dolor de compatibilidad y migración para grandes bases de código, especialmente en finanzas. Muchos coinciden en que la API de datetime de Python ha sido propensa a errores durante años, pero discrepan fuertemente sobre si la deprecación y eventual eliminación es una corrección necesaria o un cambio innecesariamente rompedor.
Datetimes ingenuos vs. conscientes de la zona horaria
- Muchos coinciden en que la división de Python entre “ingenua” y “consciente” es propensa a errores, especialmente cuando se mezclan silenciosamente.
- La queja principal:
utcnow()suena como si devolviera un datetime consciente de UTC, pero en realidad devuelve datos ingenuos con semántica local; esto ha causado errores sutiles. - Algunos sostienen que, conceptualmente, “todos los datetimes reales tienen una zona horaria” y que los datetimes ingenuos deberían ser raros o tipos claramente separados.
- Otros insisten en que UTC ingenuo es una convención interna válida y eficiente, ampliamente usada (por ejemplo, en finanzas), y que deprecierla es disruptivo.
Casos de uso en los que se necesitan horas locales / ingenuas
- Eventos recurrentes o locales: alarmas a las “8am local”, citas futuras a las “10am en Europe/London”, horarios de apertura de tiendas a las “9:30am local”, reuniones recurrentes, horarios de apertura de bolsas.
- Estos no se mapean limpiamente a un único instante UTC, especialmente cuando los gobiernos cambian las reglas de DST o los offsets después de programarlos.
- Algunos quieren tipos distintos: marcas de tiempo/instantes vs fecha/hora locales vs reglas recurrentes, para evitar usos incorrectos.
Almacenamiento e intercambio del tiempo
- Fuerte apoyo a “almacenar eventos pasados en UTC, convertir al mostrar”; desacuerdo sobre los eventos futuros.
- Desacuerdo sobre el mejor almacenamiento:
- Enteros epoch: simples y rápidos, pero necesitan conocimiento implícito del epoch, las unidades y UTC; son ambiguos sin metadatos.
- Cadenas ISO‑8601: autoexplicativas y legibles por humanos, pero más lentas y pesadas.
- Tipos de BD: advertencias de que “TIMESTAMP WITH TIME ZONE” en algunas bases de datos solo almacena UTC y descarta la zona original; otros argumentan que sigue siendo útil.
DST, offsets y zonas horarias extrañas
- Los participantes enumeran realidades complicadas: offsets de media hora y de 45 minutos, offsets históricos extraños, cambios políticos frecuentes, cambios de DST, horas duplicadas.
- Se señala que la conversión UTC↔local no es una función pura estable para fechas futuras; se necesitan nombres de zona y bases de datos tz actualizadas.
Qué usar en lugar de utcnow y diseño de API
- Patrón recomendado:
datetime.now(timezone.utc)(o equivalente), posiblemente eliminandotzinfosolo en los límites de serialización. - Algunos desearían que Python tuviera tipos separados para datetimes con zona y sin zona (como Java, Rust, Elixir) y que “aware” hubiera sido el valor predeterminado desde el principio.
- Otros argumentan que Python ya tiene características dinámicas y mocking, así que las abstracciones pesadas (como el proveedor de tiempo de .NET) son excesivas.
Compatibilidad hacia atrás e impacto en el ecosistema
- Preocupa que la deprecación afecte a grandes bases de código heredadas y financieras que estandarizaron UTC ingenuo.
- Contraargumento: deprecación primero, eliminación después, es más seguro que cambiar silenciosamente la semántica; el análisis estático y en tiempo de ejecución puede encontrar los puntos de llamada.
- Debate más amplio sobre la disposición de Python a romper APIs en 3.x frente a culturas de “nunca romper” (C, Java), y si los cambios graduales son mejores que roturas grandes al estilo “Python 4”.