Trabajar con fechas y horas ha sido durante mucho tiempo un punto débil para los desarrolladores de JavaScript. El objeto nativo Date
, con sus peculiaridades y limitaciones, ha empujado a muchos desarrolladores hacia bibliotecas de terceros como Moment.js o date-fns. Sin embargo, el comité TC39 (responsable de la evolución de JavaScript) ha estado trabajando en una solución: la API Temporal. Este enfoque moderno e integral para el manejo de fechas y horas promete resolver los problemas de larga data con las operaciones temporales de JavaScript.
El problema con el objeto Date de JavaScript
Antes de sumergirse en la API Temporal, es importante comprender las limitaciones del objeto Date
actual:
- Estado mutable: los objetos Date se pueden modificar en el lugar, lo que lleva a efectos secundarios inesperados
- Funcionalidad limitada: las operaciones simples como agregar días o comparar fechas requieren código complejo
- Inconsistencias en el análisis de cadenas: el análisis de fechas a partir de cadenas es notoriamente poco confiable en todos los navegadores
- Sin soporte de zona horaria: manejo deficiente de las zonas horarias más allá de UTC y la hora local
- Solo calendario gregoriano: sin soporte para otros sistemas de calendario
- API confusa: métodos como
getMonth()
que devuelven valores indexados en cero (0-11 en lugar de 1-12)
Estos problemas han hecho que trabajar con fechas en JavaScript sea propenso a errores y frustrante, lo que ha llevado a la adopción generalizada de bibliotecas de terceros.
Presentación de la API Temporal
La API Temporal es una adición propuesta a JavaScript que proporciona una solución moderna e integral para trabajar con fechas y horas. Está diseñado como un objeto global (Temporal
) que actúa como un espacio de nombres de nivel superior (similar al objeto Math
), que contiene varias clases para diferentes operaciones de fecha y hora.
Los principios clave detrás de la API Temporal incluyen:
- Inmutabilidad: todos los objetos Temporal son inmutables, lo que elimina los efectos secundarios
- Claridad: clara separación entre diferentes tipos de conceptos de fecha/hora
- Soporte de zona horaria: soporte de primera clase para todas las zonas horarias, incluida la aritmética segura para DST
- Múltiples sistemas de calendario: soporte para calendarios no gregorianos
- Precisión: precisión de nanosegundos para cálculos de tiempo
- Consistencia: análisis y formato estandarizados
Tipos de datos clave en la API Temporal
La API Temporal introduce varias clases especializadas para manejar diferentes aspectos de la fecha y la hora:
Tipos de datos simples (sin información de zona horaria)
- Temporal.PlainDate: representa una fecha de calendario (por ejemplo, 24 de agosto de 2006) sin información de hora o zona horaria
- Temporal.PlainTime: representa la hora del reloj (por ejemplo, 7:39 PM) sin fecha ni zona horaria
- Temporal.PlainDateTime: combina la fecha y la hora del reloj sin información de zona horaria
- Temporal.PlainYearMonth: representa un año y un mes específicos (por ejemplo, octubre de 2020)
- Temporal.PlainMonthDay: representa un mes y un día sin año (por ejemplo, 14 de julio)
Tipos de datos zonificados (con información de zona horaria)
- Temporal.ZonedDateTime: un objeto de fecha/hora con reconocimiento de zona horaria y reconocimiento de calendario que representa un evento real en un momento particular desde la perspectiva de una región particular
- Temporal.Instant: representa un punto fijo en el tiempo (hora exacta), sin tener en cuenta el calendario o la ubicación
Tipos adicionales
- Temporal.Duration: expresa una duración de tiempo (por ejemplo, 5 minutos y 30 segundos)
- Temporal.TimeZone: representa una zona horaria y proporciona métodos de conversión
- Temporal.Calendar: representa un sistema de calendario
Trabajar con la API Temporal
Creación de objetos temporales
La API Temporal proporciona varias formas de crear objetos:
// Getting the current date and time
const now = Temporal.Now.plainDateTimeISO();
console.log(now.toString()); // e.g., 2023-08-24T14:30:45.123456789
// Just the date
const today = Temporal.Now.plainDateISO();
console.log(today.toString()); // e.g., 2023-08-24
// Just the time
const currentTime = Temporal.Now.plainTimeISO();
console.log(currentTime.toString()); // e.g., 14:30:45.123456789
// Creating objects from components
const date = Temporal.PlainDate.from({ year: 2023, month: 8, day: 24 });
const time = Temporal.PlainTime.from({ hour: 14, minute: 30, second: 45 });
const dateTime = Temporal.PlainDateTime.from({
year: 2023,
month: 8,
day: 24,
hour: 14,
minute: 30,
second: 45
});
// Creating from ISO strings
const dateFromString = Temporal.PlainDate.from("2023-08-24");
const timeFromString = Temporal.PlainTime.from("14:30:45");
const dateTimeFromString = Temporal.PlainDateTime.from("2023-08-24T14:30:45");
Trabajar con zonas horarias
La API Temporal facilita mucho el trabajo con zonas horarias:
// Current time in the local timezone
const localTime = Temporal.Now.zonedDateTimeISO();
console.log(localTime.toString());
// e.g., 2023-08-24T14:30:45+01:00[Europe/London]
// Current time in a specific timezone
const tokyoTime = Temporal.Now.zonedDateTimeISO("Asia/Tokyo");
console.log(tokyoTime.toString());
// e.g., 2023-08-24T22:30:45+09:00[Asia/Tokyo]
// Converting between timezones
const nyTime = localTime.withTimeZone("America/New_York");
console.log(nyTime.toString());
// e.g., 2023-08-24T09:30:45-04:00[America/New_York]
Aritmética de fecha y hora
Una de las características más poderosas de la API Temporal son sus operaciones aritméticas intuitivas:
// Adding time
const tomorrow = today.add({ days: 1 });
const nextWeek = today.add({ days: 7 });
const twoHoursLater = currentTime.add({ hours: 2 });
// Subtracting time
const yesterday = today.subtract({ days: 1 });
const lastWeek = today.subtract({ days: 7 });
const twoHoursEarlier = currentTime.subtract({ hours: 2 });
// Working with durations
const duration = Temporal.Duration.from({ hours: 2, minutes: 30 });
const laterTime = currentTime.add(duration);
// Finding the difference between two dates
const date1 = Temporal.PlainDate.from("2023-01-01");
const date2 = Temporal.PlainDate.from("2023-08-24");
const difference = date1.until(date2);
console.log(difference.toString()); // P236D (ISO 8601 duration format)
console.log(difference.days); // 236
Modificación de componentes con "with"
La API Temporal proporciona una forma limpia de crear nuevos objetos con componentes modificados:
// Changing the year of a date
const nextYear = date.with({ year: date.year + 1 });
// Setting specific components
const newDateTime = dateTime.with({ hour: 12, minute: 0, second: 0 });
console.log(newDateTime.toString()); // 2023-08-24T12:00:00
Comparación de objetos temporales
La API proporciona métodos de comparación intuitivos:
const date1 = Temporal.PlainDate.from("2023-08-24");
const date2 = Temporal.PlainDate.from("2023-09-15");
console.log(date1.equals(date2)); // false
console.log(date1.equals(date1)); // true
console.log(date1.before(date2)); // true
console.log(date1.after(date2)); // false
console.log(date1.since(date2).days); // -22
Manejo del DST y tiempos ambiguos
La API Temporal maneja elegantemente las complejidades de las transiciones del horario de verano:
// Creating a time that falls during a DST transition
const dstTime = Temporal.ZonedDateTime.from({
timeZone: "America/New_York",
year: 2023,
month: 11,
day: 5,
hour: 1,
minute: 30
});
// The API allows you to specify how to handle ambiguous times
const dstTimeExact = Temporal.ZonedDateTime.from({
timeZone: "America/New_York",
year: 2023,
month: 11,
day: 5,
hour: 1,
minute: 30,
disambiguation: "earlier" // Options: 'earlier', 'later', 'compatible', 'reject'
});
Soporte para calendarios no gregorianos
A diferencia del objeto Date
, la API Temporal admite múltiples sistemas de calendario:
// Creating a date in the Hebrew calendar
const hebrewDate = Temporal.PlainDate.from({
year: 5783,
month: 5,
day: 15,
calendar: "hebrew"
});
// Converting between calendar systems
const gregorianDate = hebrewDate.withCalendar("iso8601");
Análisis y formato
La API Temporal proporciona métodos integrados para el análisis y el formato:
// Parsing from strings
const date = Temporal.PlainDate.from("2023-08-24");
// Custom formatting
const options = {
year: 'numeric',
month: 'long',
day: 'numeric'
};
console.log(date.toLocaleString("en-US", options)); // August 24, 2023
Estado actual y soporte del navegador
Al momento de escribir esto, la API Temporal se encuentra en la Etapa 3 en el proceso de propuesta de TC39, lo que significa que está cerca de ser finalizada, pero aún no forma parte del estándar oficial de ECMAScript. Si bien el soporte nativo del navegador aún está pendiente, los desarrolladores pueden usar polyfills como @js-temporal/polyfill
para comenzar a usar esta API hoy:
// Installing the polyfill
// npm install @js-temporal/polyfill
// Using in your code
import { Temporal } from "@js-temporal/polyfill";
const now = Temporal.Now.plainDateTimeISO();
Conclusión
La API Temporal representa una mejora significativa en las capacidades de manejo de fechas y horas de JavaScript. Al abordar los problemas de larga data con el objeto Date
y proporcionar una API integral e intuitiva, promete hacer que trabajar con conceptos temporales en JavaScript sea mucho más agradable y menos propenso a errores.
Los beneficios clave de la API Temporal incluyen:
- Inmutabilidad: todas las operaciones devuelven objetos nuevos, lo que evita los efectos secundarios
- Claridad: clara distinción entre diferentes tipos de fechas y horas
- Integral: cubre todo, desde fechas simples hasta operaciones complejas con reconocimiento de zona horaria
- Intuitivo: métodos como
add()
,subtract()
ywith()
hacen que las operaciones comunes sean sencillas - Preciso: admite precisión de nanosegundos
- Global: soporte para múltiples zonas horarias y sistemas de calendario
Mientras esperamos que los navegadores implementen esta API de forma nativa, el polyfill permite a los desarrolladores comenzar a beneficiarse de estas mejoras hoy. A medida que las aplicaciones web continúan volviéndose más globales y sensibles al tiempo, la API Temporal sin duda se convertirá en una herramienta esencial en el conjunto de herramientas de todo desarrollador de JavaScript, poniendo fin finalmente a la necesidad de bibliotecas externas para operaciones básicas de fecha y hora.
Al adoptar la API Temporal, los desarrolladores pueden escribir código más limpio y fácil de mantener que maneje correctamente las complejidades de las fechas, las horas y las zonas horarias, lo que resulta en mejores experiencias de usuario en todo el mundo.