6 puntos por GN⁺ 2026-01-13 | 1 comentarios | Compartir por WhatsApp
  • Señala la incompletitud e inconsistencia del objeto Date existente en JavaScript e introduce la API Temporal como su reemplazo
  • Date funciona como un objeto mutable (mutable object), lo que no encaja con el concepto real de fecha, y además tiene problemas estructurales como errores de parseo y limitaciones en el manejo de zonas horarias
  • Temporal ofrece un nuevo modelo para manejar fecha y hora basado en inmutabilidad, e incluye clases más específicas como PlainDate, ZonedDateTime y Duration
  • Los métodos de Temporal no modifican el objeto existente, sino que devuelven un nuevo objeto, lo que permite operaciones encadenadas más claras y seguras
  • Temporal se encuentra actualmente en la etapa 3 de estandarización (Stage 3) y ya cuenta con soporte experimental en navegadores modernos como Chrome y Firefox

Problemas del objeto Date de JavaScript

  • El constructor Date genera confusión por sus reglas de parseo inconsistentes y su indexación poco intuitiva
    • Ejemplo: el mes (month) empieza en 0, mientras que el día (day) y el año (year) empiezan en 1
    • La cadena "99" se interpreta como 1999, mientras que "100" se interpreta como el año 0100, lo que demuestra la falta de consistencia
  • Date está diseñado con énfasis en el tiempo (time) y almacena internamente un timestamp Unix (en milisegundos)
  • El soporte de zona horaria (time zone) es limitado y no reconoce correctamente el horario de verano (DST) ni los calendarios no gregorianos
  • Por estas limitaciones, es común depender de grandes librerías de terceros como Moment.js o date-fns, lo que puede traducirse en peor rendimiento

Conflicto entre inmutabilidad y referencias

  • En JavaScript, los valores primitivos (primitive) son inmutables y se almacenan por valor, mientras que los objetos (object) se almacenan por referencia (reference) y pueden modificarse
  • Date es un objeto creado mediante un constructor (constructor), por lo que es mutable
    • Ejemplo: al llamar setMonth() o setDate(), el objeto original se modifica directamente
  • Esto provoca cambios inesperados en el valor entre variables que apuntan al mismo objeto
    • Ejemplo: si una función recibe today como argumento y modifica la fecha internamente, el today original también cambia

Temporal: una nueva API de fecha y hora

  • Temporal es un objeto de espacio de nombres (namespace object), no un constructor, con una estructura similar a Math
    • Componentes principales: PlainDate, PlainDateTime, PlainTime, ZonedDateTime, Duration, Now, etc.
  • Temporal.Now devuelve el momento actual en distintos formatos
    • plainDateISO() → fecha en formato ISO
    • zonedDateTimeISO() → fecha y hora con zona horaria
  • Los objetos de Temporal ofrecen un sistema de métodos claro
    • Permiten operaciones con unidades explícitas como add({ days: 1 }) y subtract({ years: 2 })
    • No modifican el objeto existente, sino que devuelven uno nuevo, manteniendo la inmutabilidad

Cómo funciona Temporal y cuáles son sus ventajas

  • Los objetos de Temporal siguen siendo objetos, pero usan un patrón de uso intencionalmente inmutable
    • Ejemplo: today.add({ days: 1 }) devuelve un nuevo objeto de fecha, mientras que el today original no cambia
  • Ofrece una sintaxis más concisa y clara que Date
    • Ejemplo:
      const today = Temporal.Now.plainDateISO();  
      console.log(`Tomorrow will be ${ today.add({ days: 1 }) }. Today is ${ today }.`);  
      // Resultado: Tomorrow will be 2026-01-01. Today is 2025-12-31.  
      
  • Responde mejor a necesidades modernas como la definición de zonas horarias, el cálculo de períodos y el mantenimiento del formato ISO
  • Con encadenamiento de métodos como add, subtract, since y until, es posible expresar de forma concisa cálculos de fecha complejos

Estado de la estandarización y perspectivas futuras

  • Temporal ya alcanzó la etapa 3 de la propuesta de ECMAScript (Stage 3), en la que se recomienda su implementación en navegadores
  • Chrome y Firefox ya comenzaron a ofrecer soporte experimental, y se espera que otros navegadores también lo adopten
  • Desde ahora, los desarrolladores pueden participar en la mejora de la especificación mediante pruebas y envío de retroalimentación
  • Date seguirá existiendo, pero todo apunta a que en el futuro Temporal será la forma predeterminada de manejar fechas
  • El artículo cierra diciendo que “debió haberse reemplazado en 1995, pero incluso ahora, Temporal.Now llega en el momento ideal”

1 comentarios

 
GN⁺ 2026-01-13
Comentarios en Hacker News
  • Este artículo trata varios comportamientos absurdos del constructor Date de JavaScript
    En particular, explica el problema de que el formato 'YYYY-MM-DD' se interpreta como medianoche UTC, por lo que en la zona horaria local puede correrse un día
    Originalmente, en ISO 8601, si no se especifica una zona horaria debería asumirse la hora local, pero por un error al redactar la especificación de ES5 se trató como “Z” (UTC)
    Después se intentó corregir en ES2015, pero como muchísimos sitios web dependían del comportamiento incorrecto anterior, se revirtió por compatibilidad web
    Para más detalles, ver la sección Broken Parser

    • Hubiera estado bien algo como una directiva 'strict datetime', al estilo de 'use strict'
      Así se habría podido aplicar el comportamiento correcto de forma optativa, sin problemas de incompatibilidad con el código existente
      O también podría haberse usado un enfoque como import Date from 'browser:date', cargando un objeto global corregido desde un módulo interno
    • Yo antes también separaba manualmente las cadenas para crear objetos de fecha sin zona horaria
      No tiene sentido que un valor que solo representa una fecha, como un cumpleaños, cambie por culpa de la zona horaria
      Recuerdo que Outlook antes guardaba los cumpleaños con zona horaria incluida, así que cada vez que uno cambiaba de país el cumpleaños se movía un día
    • La expresión “fue sacrificado en el altar de la compatibilidad web” resulta muy impactante
      Pero, ¿había alguna alternativa? Forzar bifurcaciones por versión del navegador, como en la era de IE5, probablemente habría sido peor
    • En el sitio jsdate.wtf se pueden experimentar directamente los comportamientos extrañísimos de JS Date
    • Pensar que estos problemas son la fuente de innumerables bugs pequeños da risa y tristeza al mismo tiempo
  • Realmente envidio la forma de manejar el tiempo en Rails y Ruby
    Una API como Time.current.in_time_zone('America/Los_Angeles') + 3.days - 4.months + 1.hour es intuitiva y poderosa
    Ruby sobrecarga el objeto Time como un único objeto consistente, así que casi no hay que preocuparse por conversiones o casteos
    En JS sería genial poder escribir algo tan simple como new Date().add({ days: 1 })

    • Pero también se cuestiona si una sintaxis como “3.days - 4.months + 1.hour” realmente es buena
      Además, también es debatible si sobrecargar la librería core es de verdad una buena aproximación
  • Es una lástima que Safari todavía no soporte la API Temporal
    Ojalá la soporte el próximo año

  • JavaScript Date tiene muchos problemas, pero no creo que el hecho de ser un objeto sea en sí el principal
    Habría sido mejor que fuera inmutable, pero no sorprende que un objeto mutable cambie

    • El problema es que otro código puede modificar implícitamente el objeto Date que yo estaba usando
      El verdadero riesgo de la mutabilidad aparece en los cambios no locales, no en los locales
  • Es incómodo que la API Temporal no maneje en absoluto la información de segundos intercalares (leap second)
    Quiero crear una herramienta de JS para cálculos astronómicos, pero para convertir a UTC hacen falta datos de segundos intercalares
    Hay alternativas como temporal-tai, pero tener que mantener el archivo de segundos intercalares del lado del cliente es muy engorroso
    Por SOP (política CORS), tampoco se puede traer directamente el archivo desde un sitio externo
    Los navegadores se actualizan periódicamente, así que resulta extraño que no incluyan esta información

    • Es un malentendido pensar que SOP bloquea el archivo de segundos intercalares
      Si el servidor configura el encabezado Access-Control-Allow-Origin o lo ofrece como archivo JS, sí se puede
      Aun así, que el navegador incluya y mantenga sus propios datos de segundos intercalares puede ser costoso
    • Decir que “solo maneja UTC” no es preciso
      UTC, por definición, incluye segundos intercalares, así que en realidad sería más correcto decir que solo maneja tiempo POSIX
  • En el ejemplo de código, debería decir que desde "50", y no "33", se interpreta como años de 1900; es solo una corrección de typo

  • Estoy usando el polyfill de Temporal y hasta ahora me ha gustado mucho

    • Eso sí, pesa 51 KB, así que no es precisamente ligero (enlace de bundlephobia)
      En servidores o apps grandes está bien, pero para apps pequeñas puede ser una carga
    • También surgió la pregunta de cómo se compara frente a moment o luxon
  • Curiosamente, el artículo no menciona para nada Date.now()
    Para compararlo con Temporal, debería haberlo usado como punto de referencia
    Esta función devuelve el tiempo transcurrido en milisegundos desde el 1 de enero de 1970
    Temporal tiene una API más amable, pero en el fondo su objetivo es representar la distancia relativa del tiempo

    • Pero también existen los bugs relacionados con timestamps mencionados en el artículo
      Entonces surge la duda de cómo convertirlos al formato deseado sin pasar por Date
  • Se deja una corrección pequeña pero importante: no es “daylight savings time”, sino “daylight saving time”

  • Hasta ahora no sabía que JS Date estuviera tan mal hecho

    • Lo más triste es que estos problemas ya eran evidentes desde 1995
      Si en ese momento hubieran sido un poco más cuidadosos, muchísimos desarrolladores no habrían caído en estas trampas