Introducción
\nTrabajar con fechas y horas es una de las tareas más comunes, pero también más engañosas en el desarrollo web. El objeto estándar Date en JavaScript, a pesar de su versatilidad, tiene una serie de limitaciones: falta de soporte integrado para zonas horarias (excepto UTC y la hora local), métodos incómodos para formatear y dificultades para calcular la diferencia entre fechas. En este artículo, analizaremos técnicas avanzadas para trabajar con fechas en el entorno Node.js que le ayudarán a escribir código confiable y comprensible.
1. Intl.DateTimeFormat: Formateo potente sin bibliotecas externas
\nJavaScript moderno proporciona la API integrada Intl.DateTimeFormat, que permite formatear fechas y horas de manera flexible teniendo en cuenta la configuración regional. Es la herramienta ideal si no necesita toda la potencia de las bibliotecas externas.
Uso básico
\nCree una instancia del formateador, pasando la configuración regional y un objeto con opciones:
\nconst date = new Date('2024-12-25T10:30:00Z');\n\n// Formateo para la configuración regional rusa\nconst ruFormatter = new Intl.DateTimeFormat('ru-RU', {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n weekday: 'long',\n hour: '2-digit',\n minute: '2-digit',\n timeZone: 'Europe/Moscow'\n});\n\nconsole.log(ruFormatter.format(date));\n// Salida: "среда, 25 декабря 2024 г. в 13:30"\n\nTrabajo con zonas horarias
\nLa ventaja clave de Intl.DateTimeFormat es el soporte de zonas horarias a través de la opción timeZone. Puede mostrar la misma fecha en diferentes zonas horarias:
const date = new Date();\n\nconst formatters = {\n 'Nueva York': new Intl.DateTimeFormat('en-US', { timeZone: 'America/New_York', dateStyle: 'full', timeStyle: 'long' }),\n 'Tokio': new Intl.DateTimeFormat('ja-JP', { timeZone: 'Asia/Tokyo', dateStyle: 'full', timeStyle: 'long' }),\n 'Londres': new Intl.DateTimeFormat('en-GB', { timeZone: 'Europe/London', dateStyle: 'full', timeStyle: 'long' })\n};\n\nfor (const [city, fmt] of Object.entries(formatters)) {\n console.log(`${city}: ${fmt.format(date)}`);\n}\n\nFormateo de rangos de fechas
\nLa API también puede formatear rangos usando el método formatRange:
const start = new Date('2024-01-01');\nconst end = new Date('2024-01-05');\n\nconst rangeFormatter = new Intl.DateTimeFormat('ru-RU', {\n month: 'long',\n day: 'numeric'\n});\n\nconsole.log(rangeFormatter.formatRange(start, end));\n// Salida: "1–5 января"\n\n2. Manipulaciones de fechas: suma, resta y diferencia
\nEl Date estándar no es adecuado para la aritmética. Consideremos dos enfoques: JavaScript puro y bibliotecas populares.
JavaScript puro: trabajo con milisegundos
\nLa forma más sencilla es convertir la fecha a Unix timestamp (milisegundos desde el 1 de enero de 1970) y realizar las operaciones:
\nfunction addDays(date, days) {\n const result = new Date(date);\n result.setTime(result.getTime() + days * 24 * 60 * 60 * 1000);\n return result;\n}\n\nfunction diffDays(date1, date2) {\n const msDiff = Math.abs(date2.getTime() - date1.getTime());\n return Math.floor(msDiff / (1000 * 60 * 60 * 24));\n}\n\nconst today = new Date('2024-10-01');\nconst future = addDays(today, 30);\nconsole.log(future); // 2024-10-31\nconsole.log(diffDays(today, future)); // 30\nDesventaja: no tiene en cuenta el cambio al horario de verano, los segundos intercalares ni las diferentes longitudes de los meses.
\n\nBiblioteca date-fns: enfoque funcional y ligero
\ndate-fns es una biblioteca modular, donde cada función es un módulo independiente. Esto permite no inflar el bundle:
// Instalación: npm install date-fns\nconst { addDays, subMonths, differenceInDays, format } = require('date-fns');\nconst { ru } = require('date-fns/locale');\n\nconst startDate = new Date(2024, 0, 15); // 15 de enero de 2024\n\nconst plusWeek = addDays(startDa