Trabajo avanzado con fechas y horas en TypeScript: métodos y ejemplos

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Trabajo avanzado con fechas y horas en TypeScript: desde el tipado hasta operaciones complejas

\n\n

Trabajar con fechas y horas es una de las tareas más comunes y a la vez más engañosas en el desarrollo web. A nivel avanzado, el simple uso de new Date() ya no es suficiente. TypeScript proporciona un potente sistema de tipos, y las bibliotecas modernas (Luxon, Date-fns) permiten escribir código seguro, predecible y eficiente. En este artículo, analizaremos técnicas avanzadas: tipado estricto, trabajo con zonas horarias, formato y análisis complejos, así como la creación de utilidades propias.

\n\n

1. Tipado estricto de fechas: tipos personalizados y Branded Types

\n\n

El tipo Date en TypeScript no protege contra el envío de un valor incorrecto. Por ejemplo, una función que espera una fecha de nacimiento podría recibir la marca de tiempo actual. La solución es usar Branded Types (tipos etiquetados) o Nominal Typing.

\n\n
// Branded Type para fecha de nacimiento\ntype BirthDate = Date & { __brand: 'BirthDate' };\n\nfunction createBirthDate(date: Date): BirthDate {\n  // Validación: la fecha no debe ser futura\n  if (date.getTime() > Date.now()) {\n    throw new Error('La fecha de nacimiento no puede ser futura');\n  }\n  return date as BirthDate;\n}\n\nfunction calculateAge(birthDate: BirthDate): number {\n  const diff = Date.now() - birthDate.getTime();\n  return Math.floor(diff / (1000 * 60 * 60 * 24 * 365.25));\n}\n\n// Uso\nconst rawDate = new Date('1990-05-15');\nconst birth = createBirthDate(rawDate);\nconsole.log(calculateAge(birth)); // OK\n\n// Error: Argument of type 'Date' is not assignable to parameter of type 'BirthDate'\n// console.log(calculateAge(new Date())); \n
\n\n

Este enfoque garantiza que solo una fecha de nacimiento validada llegue a la función calculateAge. Para escenarios más complejos, se pueden crear tipos para marcas de tiempo (UnixTimestamp), intervalos (TimeInterval), etc.

\n\n

2. Formato y análisis avanzados con Intl.DateTimeFormat

\n\n

El objeto integrado Intl.DateTimeFormat permite formatear fechas de manera flexible sin bibliotecas externas. A nivel avanzado, podemos crear formateadores reutilizables y manejar configuraciones regionales complejas.

\n\n
// Creación de un formateador con opciones\nconst formatter = new Intl.DateTimeFormat('es-ES', {\n  year: 'numeric',\n  month: 'long',\n  day: 'numeric',\n  weekday: 'long',\n  hour: '2-digit',\n  minute: '2-digit',\n  timeZone: 'Europe/Madrid',\n});\n\n// Formateo\nconsole.log(formatter.format(new Date())); \n// "viernes, 25 de octubre de 2024, 14:30"\n\n// Análisis (utilidad personalizada)\nfunction parseLocalizedDate(dateStr: string, locale: string): Date | null {\n  const parts = dateStr.match(/(\\d{4})-(\\d{2})-(\\d{2})/);\n  if (!parts) return null;\n  \n  const [, year, month, day] = parts;\n  return new Date(parseInt(year), parseInt(month) - 1, parseInt(day));\n}\n
\n\n

Consejo: Para mejorar el rendimiento, cree formateadores una sola vez y reutilícelos. Evite crear una nueva instancia en cada llamada.

\n\n

3. Trabajo con zonas horarias y la biblioteca Luxon

\n\n

El Date integrado maneja mal las zonas horarias. Luxon es una biblioteca moderna del creador de Moment.js que se integra perfectamente con TypeScript.

\n\n
import { DateTime, Settings } from 'luxon';\n\n// Configuración de la zona horaria predeterminada\nSettings.defaultZone = 'Europe/Madrid';\n\n// Creación de una fecha con zona explícita\nconst meeting = DateTime.fromISO('2024-11-01T15:00:00', { zone: 'America/New_York' });\nconsole.log(meeting.toISO()); // 2024-11-01T15:00:00.000-04:00\n\n// Conversión a otra zona\nconst madridTime = meeting.setZone('Europe/Madrid');\nconsole.log(madridTime.toFormat('dd.MM.yyyy HH:mm')); // 01.11.2024 21:00\n\n// Trabajo con intervalos\nconst start = DateTi                

Blogs

Book Recommendations