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, cuya incorporación al estándar ECMAScript ya está confirmada, 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. Llamar a astimezone() sobre un datetime ingenuo no lanza ningún error: el valor se interpreta como la hora local del sistema y se vuelve silenciosamente incorrecto. Las comparaciones de orden y la resta entre valores ingenuos y conscientes sí lanzan TypeError, mientras que solo la comparación de igualdad devuelve False sin protestar, de modo que el punto donde falla el código va en contra de la intuición. 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 un diseño maduro que las API de fecha y hora de lenguajes y bibliotecas posteriores toman como referencia de forma reiterada. 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.