Español

Una guía detallada de la API Temporal de JavaScript, una solución moderna para manejar fechas y horas eficazmente en diversos contextos internacionales.

API Temporal de JavaScript: Manejo Moderno de Fecha y Hora para una Audiencia Global

El objeto `Date` de JavaScript ha sido durante mucho tiempo una fuente de frustración para los desarrolladores. Su mutabilidad, su API inconsistente y su pobre soporte para zonas horarias han llevado a la creación de numerosas bibliotecas como Moment.js y date-fns para llenar los vacíos. Ahora, con la API Temporal, JavaScript ofrece una solución moderna e integrada para manejar fechas y horas con mayor claridad y precisión. Este artículo proporciona una visión general completa de la API Temporal, centrándose en sus características, beneficios y uso en diversos contextos internacionales.

¿Qué es la API Temporal?

La API Temporal es un nuevo objeto global en JavaScript diseñado para solucionar las deficiencias del objeto `Date`. Proporciona una API limpia e inmutable para trabajar con fechas, horas, zonas horarias y sistemas de calendario. De manera crucial, su objetivo es representar los conceptos de fecha y hora de una manera que se alinee más estrechamente con el uso y las expectativas del mundo real, haciendo que la internacionalización sea mucho más sencilla.

Características Clave:

Objetos Temporales Básicos

La API Temporal introduce varios tipos de objetos nuevos. Aquí están algunos de los principales:

Trabajando con Fechas

Creando un `Temporal.PlainDate`

Para crear un `Temporal.PlainDate`, puedes usar el constructor:

const plainDate = new Temporal.PlainDate(2024, 10, 27); // Año, Mes (1-12), Día
console.log(plainDate.toString()); // Salida: 2024-10-27

También puedes usar el método `from`, que acepta una cadena en formato ISO 8601:

const plainDateFromString = Temporal.PlainDate.from('2024-10-27');
console.log(plainDateFromString.toString()); // Salida: 2024-10-27

Obteniendo Componentes de la Fecha

Puedes acceder a los componentes individuales de la fecha usando propiedades como `year`, `month` y `day`:

console.log(plainDate.year); // Salida: 2024
console.log(plainDate.month); // Salida: 10
console.log(plainDate.day); // Salida: 27

Aritmética de Fechas

Para sumar o restar días, semanas, meses o años, usa los métodos `plus` y `minus`. Estos métodos devuelven un nuevo objeto `Temporal.PlainDate`:

const nextWeek = plainDate.plus({ days: 7 });
console.log(nextWeek.toString()); // Salida: 2024-11-03

const lastMonth = plainDate.minus({ months: 1 });
console.log(lastMonth.toString()); // Salida: 2024-09-27

Comparando Fechas

Puedes comparar fechas usando el método `compare`:

const date1 = new Temporal.PlainDate(2024, 10, 27);
const date2 = new Temporal.PlainDate(2024, 11, 15);

console.log(Temporal.PlainDate.compare(date1, date2)); // Salida: -1 (date1 es anterior a date2)

Trabajando con Horas

Creando un `Temporal.PlainTime`

Para crear un `Temporal.PlainTime`, usa el constructor:

const plainTime = new Temporal.PlainTime(10, 30, 0); // Hora, Minuto, Segundo
console.log(plainTime.toString()); // Salida: 10:30:00

O usa el método `from` con una cadena de tiempo ISO 8601:

const plainTimeFromString = Temporal.PlainTime.from('10:30:00');
console.log(plainTimeFromString.toString()); // Salida: 10:30:00

Obteniendo Componentes de la Hora

console.log(plainTime.hour); // Salida: 10
console.log(plainTime.minute); // Salida: 30
console.log(plainTime.second); // Salida: 0

Aritmética de Horas

const later = plainTime.plus({ minutes: 15 });
console.log(later.toString()); // Salida: 10:45:00

Trabajando con Fecha y Hora Juntas

Creando un `Temporal.PlainDateTime`

Puedes crear un `Temporal.PlainDateTime` directamente o combinando un `Temporal.PlainDate` y un `Temporal.PlainTime`:

const plainDateTime = new Temporal.PlainDateTime(2024, 10, 27, 10, 30, 0);
console.log(plainDateTime.toString()); // Salida: 2024-10-27T10:30:00

const date = new Temporal.PlainDate(2024, 10, 27);
const time = new Temporal.PlainTime(10, 30, 0);
const combinedDateTime = date.toPlainDateTime(time);
console.log(combinedDateTime.toString()); // Salida: 2024-10-27T10:30:00

Zonas Horarias

Manejar correctamente las zonas horarias es crucial para aplicaciones que tratan con usuarios en diferentes ubicaciones. La API Temporal proporciona un soporte robusto para zonas horarias a través de los objetos `Temporal.ZonedDateTime` y `Temporal.TimeZone`.

Creando un `Temporal.ZonedDateTime`

Para crear un `Temporal.ZonedDateTime`, necesitas un `Temporal.PlainDateTime` y un identificador de zona horaria. Los identificadores de zona horaria se basan en la base de datos de zonas horarias de la IANA (p. ej., `America/Los_Angeles`, `Europe/London`, `Asia/Tokyo`).

const plainDateTime = new Temporal.PlainDateTime(2024, 10, 27, 10, 30, 0);
const timeZone = 'America/Los_Angeles';
const zonedDateTime = plainDateTime.toZonedDateTime(timeZone);
console.log(zonedDateTime.toString()); // Salida: 2024-10-27T10:30:00-07:00[America/Los_Angeles] (El desfase dependerá de las reglas del DST)

Alternativamente, crea un `Temporal.ZonedDateTime` a partir de un `Instant`.

const instant = Temporal.Instant.fromEpochSeconds(1666866600); // Marca de tiempo de ejemplo
const zonedDateTimeFromInstant = instant.toZonedDateTimeISO(timeZone); // Zona horaria como 'America/Los_Angeles'
console.log(zonedDateTimeFromInstant.toString());

Convirtiendo Entre Zonas Horarias

Puedes convertir un `Temporal.ZonedDateTime` a una zona horaria diferente usando el método `withTimeZone`:

const newTimeZone = 'Europe/London';
const zonedDateTimeInLondon = zonedDateTime.withTimeZone(newTimeZone);
console.log(zonedDateTimeInLondon.toString()); // Salida: 2024-10-27T18:30:00+01:00[Europe/London]

Trabajando con Desfases de Zona Horaria

El método `getOffsetStringFor` del objeto `Temporal.TimeZone` proporciona la cadena de desfase para un `Temporal.Instant` dado:

const timeZoneObject = new Temporal.TimeZone(timeZone);
const offsetString = timeZoneObject.getOffsetStringFor(zonedDateTime.toInstant());
console.log(offsetString); // Salida: -07:00 (Dependiendo de las reglas del DST)

Es esencial usar los identificadores de zona horaria IANA correctos para cálculos precisos. Estos identificadores se mantienen y actualizan regularmente para reflejar los cambios en el horario de verano y los límites de las zonas horarias.

Duraciones

El objeto `Temporal.Duration` representa un lapso de tiempo. Se puede usar para sumar o restar de fechas y horas.

Creando un `Temporal.Duration`

Puedes crear un `Temporal.Duration` usando el constructor, especificando los años, meses, días, horas, minutos, segundos, milisegundos, microsegundos y nanosegundos:

const duration = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 8, 9); // Años, Meses, Días, Horas, Minutos, Segundos, Milisegundos, Microsegundos, Nanosegundos
console.log(duration.toString()); // Salida: P1Y2M3DT4H5M6.007008009S

O usando una cadena de duración ISO 8601:

const durationFromString = Temporal.Duration.from('P1Y2M3DT4H5M6S');
console.log(durationFromString.toString()); // Salida: P1Y2M3DT4H5M6S

Sumando Duraciones a Fechas y Horas

const plainDate = new Temporal.PlainDate(2024, 10, 27);
const duration = new Temporal.Duration(0, 0, 7); // 7 días
const newDate = plainDate.plus(duration);
console.log(newDate.toString()); // Salida: 2024-11-03

Ten en cuenta que sumar duraciones que involucran meses o años a las fechas requiere una consideración cuidadosa, ya que el número de días en un mes o año puede variar.

Sistemas de Calendario

La API Temporal admite diferentes sistemas de calendario más allá del calendario gregoriano. Esto es crucial para aplicaciones que necesitan manejar fechas en diversos contextos culturales. Aunque el soporte todavía está evolucionando, proporciona una base para una futura expansión.

Usando Calendarios Alternativos

Para usar un calendario específico, puedes especificarlo al crear objetos Temporal:

const hebrewDate = new Temporal.PlainDate(5785, 1, 1, { calendar: 'hebrew' });
console.log(hebrewDate.toString()); // La salida específica puede variar según la implementación y el formato. Requiere polyfill en muchos entornos al momento de escribir esto.

Importante: El soporte para calendarios no gregorianos podría requerir polyfills o soporte específico del navegador/entorno. Consulta la documentación de la API Temporal y las tablas de compatibilidad de navegadores para obtener la información más reciente.

Formateando Fechas y Horas

Aunque la API Temporal se centra en la manipulación de fechas y horas, el formateo generalmente se maneja con el objeto `Intl.DateTimeFormat`, que es parte de la API de Internacionalización. Los objetos Temporal funcionan perfectamente con `Intl.DateTimeFormat`.

Usando `Intl.DateTimeFormat`

Aquí se muestra cómo formatear un `Temporal.PlainDate` usando `Intl.DateTimeFormat`:

const plainDate = new Temporal.PlainDate(2024, 10, 27);
const formatter = new Intl.DateTimeFormat('es-ES', { year: 'numeric', month: 'long', day: 'numeric' });
console.log(formatter.format(plainDate)); // Salida: 27 de octubre de 2024

const formatterGerman = new Intl.DateTimeFormat('de-DE', { year: 'numeric', month: 'long', day: 'numeric' });
console.log(formatterGerman.format(plainDate)); // Salida: 27. Oktober 2024

Puedes personalizar las opciones de formato para adaptarlas a tus necesidades. El primer argumento de `Intl.DateTimeFormat` es la configuración regional (locale), que determina el idioma y las convenciones regionales utilizadas para el formato. El uso de diferentes configuraciones regionales (p. ej., 'en-US', 'de-DE', 'fr-FR', 'ja-JP') produce diferentes formatos de salida.

Formateando `Temporal.ZonedDateTime`

Formatear `Temporal.ZonedDateTime` es similar, pero también puedes incluir información de la zona horaria en la salida:

const plainDateTime = new Temporal.PlainDateTime(2024, 10, 27, 10, 30, 0);
const timeZone = 'America/Los_Angeles';
const zonedDateTime = plainDateTime.toZonedDateTime(timeZone);

const formatter = new Intl.DateTimeFormat('en-US', { year: 'numeric', month: 'long', day: 'numeric', hour: 'numeric', minute: 'numeric', timeZoneName: 'short' });
console.log(formatter.format(zonedDateTime)); // Salida: October 27, 2024, 10:30 AM PDT (La abreviatura de la zona horaria depende de las reglas del DST)

Mejores Prácticas de Internacionalización

Cuando trabajes con fechas y horas en un contexto global, ten en cuenta las siguientes mejores prácticas:

Comparando la API Temporal con el Objeto Date Heredado

Aquí hay una tabla que destaca las diferencias clave y las ventajas de la API Temporal en comparación con el objeto `Date` heredado:

Característica Objeto `Date` Heredado API Temporal
Mutabilidad Mutable (modifica el objeto original) Inmutable (devuelve nuevos objetos)
Soporte de Zona Horaria Limitado y a menudo problemático Robusto y preciso, basado en la base de datos de zonas horarias de IANA
API Inconsistente y difícil de usar Clara, consistente e intuitiva
Precisión Milisegundo Nanosegundo
Sistemas de Calendario Limitado al gregoriano Admite sistemas de calendario alternativos (con soporte en evolución)
Internacionalización Requiere bibliotecas externas para una internacionalización robusta Soporte integrado e integración perfecta con `Intl.DateTimeFormat`

Soporte de Navegadores y Polyfills

Como una API relativamente nueva, el soporte de los navegadores para la API Temporal todavía está evolucionando. Consulta las últimas tablas de compatibilidad de navegadores (p. ej., en MDN Web Docs) para ver qué navegadores y entornos la admiten de forma nativa. Para navegadores más antiguos o entornos sin soporte nativo, puedes usar polyfills para proporcionar la funcionalidad de la API Temporal. Busca "Temporal API polyfill" en la web para encontrar opciones adecuadas.

Conclusión

La API Temporal de JavaScript representa un avance significativo en el manejo de fechas y horas en JavaScript. Su inmutabilidad, API clara, soporte robusto para zonas horarias y capacidades de sistemas de calendario la convierten en una herramienta poderosa para los desarrolladores que construyen aplicaciones que necesitan trabajar con fechas y horas de manera precisa y confiable en diversos contextos internacionales. Aunque el soporte de los navegadores todavía está evolucionando, los beneficios de la API Temporal hacen que valga la pena aprenderla y adoptarla para nuevos proyectos. Al adoptar la API Temporal y seguir las mejores prácticas de internacionalización, puedes crear aplicaciones que brinden una experiencia de fecha y hora fluida y precisa para usuarios de todo el mundo.

Lecturas Adicionales