JavaScript Temporal - Corrigiendo los errores de Date
El objeto Date de JavaScript arrastra problemas desde su diseño en 1995: los meses están indexados desde cero (0 = enero), Date es mutable, el manejo de zonas horarias es débil, y el comportamiento del análisis de cadenas varía entre navegadores. La API Temporal (TC39 Stage 3) es un rediseño desde cero que aborda estos problemas a nivel fundamental.
La característica definitoria de Temporal son sus múltiples tipos para diferentes propósitos: Temporal.Instant (tiempo absoluto UTC), Temporal.ZonedDateTime (fecha y hora con zona), Temporal.PlainDateTime (fecha y hora sin zona), Temporal.PlainDate (solo fecha), Temporal.PlainTime (solo hora). La presencia o ausencia de información de zona horaria se impone a nivel de tipo en lugar de vivir implícitamente en modelos mentales.
Python datetime + zoneinfo - Evolución de la biblioteca estándar
El módulo datetime de Python distingue entre datetimes ingenuos (sin información de zona horaria) y conscientes (con información de zona horaria). Python 3.9 añadió zoneinfo, proporcionando acceso desde la biblioteca estándar a la base de datos de zonas horarias IANA y poniendo fin a la larga dependencia del paquete externo pytz.
La trampa de datetime en Python es mezclar valores ingenuos y conscientes. Las conversiones de zona horaria en datetimes ingenuos lanzan TypeError, pero los operadores de comparación a veces permiten silenciosamente la mezcla, causando errores sutiles. El patrón recomendado es mantener todos los datetimes internos como UTC conscientes, convirtiendo a hora local solo al mostrar - idéntico a la regla para la persistencia en base de datos.
Java java.time - El diseño maduro de JSR 310
El paquete java.time de Java 8 (JSR 310), liderado por Stephen Colebourne, creador de Joda-Time, es el diseño más maduro entre los principales lenguajes. Sus principios - inmutabilidad, seguridad entre hilos y clara separación de tipos (LocalDateTime, ZonedDateTime, Instant, Duration, Period) - se aplican de manera consistente en toda la API.
Una decisión de diseño destacada es la separación explícita entre Duration (cantidades basadas en tiempo en segundos y nanosegundos) y Period (cantidades basadas en fecha en años, meses, días). «Un mes después» varía de 28 a 31 días según el calendario, por lo que es fundamentalmente diferente de un número fijo de segundos. Forzar esta distinción a nivel de tipo previene toda una clase de errores aritméticos.
Errores comunes entre lenguajes
Un error común entre lenguajes es la ambigüedad al promover un valor de solo fecha a fecha-hora. Convertir «2026-05-15» a un DateTime puede usar medianoche UTC o medianoche local como referencia, con resultados que difieren en un día calendario en algunas zonas horarias. Sin especificación explícita, no se puede saber cuál eligió la biblioteca.
Otro problema compartido es el análisis permisivo de cadenas. «2026-5-15», «2026/05/15», «May 15, 2026», «15.05.2026» representan la misma fecha. Usar análisis estricto (que falle con cualquier cosa que no coincida exactamente con el formato especificado) y evitar el análisis tolerante (que adivina) es innegociable para sistemas que manejan entradas internacionalizadas.
Selección de bibliotecas y migración
Para proyectos nuevos, usa la API estándar más moderna de cada lenguaje: Temporal (mediante polyfill hasta que llegue el soporte nativo) para JavaScript, datetime + zoneinfo para Python, java.time para Java. Los proyectos existentes con Moment.js o pytz se benefician de una migración gradual: escribe código nuevo contra la API moderna y convierte el código heredado de forma oportunista cuando lo tocas por otras razones.
Las bibliotecas de terceros (Luxon, date-fns, Arrow, Pendulum) llenan vacíos útilmente en las APIs estándar pero añaden dependencias y carga de mantenimiento. Evita incorporarlas para tareas que la biblioteca estándar maneja, y resérvalas para necesidades genuinamente complejas como formateo rico de tiempo relativo o aritmética inusual de patrones recurrentes. Cuantas menos dependencias, más fácil será la próxima migración cuando los estándares avancen más.