El objeto Date: un instante en el tiempo
Una fecha en JavaScript (Date) representa un instante concreto: por dentro, no es más que un número de milisegundos desde el 1 de enero de 1970 UTC (el famoso "epoch de Unix"). Todo lo demás —años, meses, días, zonas horarias, formato— son capas que se muestran encima de ese número.
now.getTime() te devuelve los milisegundos en crudo. Todo lo que hace un Date —comparar, sumar días, dar formato— no es más que manipular ese número y luego reinterpretarlo.
Quédate con esa idea. Un Date no es "14 de marzo en París". Es un instante universal que se puede mostrar como 14 de marzo en París o 13 de marzo en Los Ángeles, según la zona horaria desde la que lo mires.
Cómo crear fechas en JavaScript
Hay cuatro formas principales de construir un Date:
Dos detalles importantes que conviene tener en cuenta:
- El constructor con partes usa los meses indexados desde cero.
2significa marzo. Enero es0. Es una fuente constante de errores off-by-one, aunque al menos la API es coherente consigo misma: en todos lados los meses empiezan en 0. new Date("2026-03-14")(sin hora) se interpreta como medianoche en UTC. En cambio,new Date("2026-03-14T09:30")(sin laZ) se interpreta como hora local. Esta asimetría es una trampa clásica.
Si solo necesitas el "ahora mismo" como número, mejor usa Date.now(), que te ahorra crear un objeto:
Date.now() es la herramienta ideal cuando quieres medir tiempos transcurridos, timeouts o cualquier cosa en la que no necesites hacer cuentas con el calendario.
Cómo obtener partes de una fecha en JavaScript
Una vez que tienes un objeto Date, puedes extraer sus componentes con los métodos getter. Cada uno viene en dos sabores: hora local y UTC.
Los métodos locales dependen de la máquina donde se ejecuta el código. Si vas a guardar o comparar fechas entre usuarios y servidores, usa UTC de forma explícita o acabarás persiguiendo bugs fantasma. Regla práctica: usa los getters de UTC para todo lo que vaya a una base de datos o a un log, y los getters locales solo cuando vayas a mostrarle algo a una persona.
No uses getYear(). Es un método heredado que devuelve year - 1900 y existe únicamente por compatibilidad. Tira siempre de getFullYear().
Formato de fecha en JavaScript para mostrar a personas
Evita date.toString() para cualquier cosa que te importe: su salida depende del locale y del motor de JavaScript. Hay dos formateadores que vale la pena conocer.
Para obtener una cadena estándar y legible por máquinas, usa toISOString():
Ese es el formato que conviene usar cuando quieres loguear, guardar algo en JSON o enviarlo por la red. Siempre está en UTC y no deja lugar a ambigüedades.
Si en cambio necesitas mostrar la fecha a una persona, usa Intl.DateTimeFormat o los métodos toLocale*, que por dentro hacen uso de él:
Intl.DateTimeFormat se encarga de los locales, las zonas horarias y cualquier combinación de campos que se te ocurra. Tíralo de ahí antes de armar a mano un ${year}-${month}-${day} — ese tipo de concatenación es justo donde aparecen los bugs clásicos del mes desfasado en uno.
Comparar fechas en JavaScript
Dos objetos Date que representan el mismo instante no son iguales con === — ese operador compara identidad de objetos, no valor. Lo correcto es comparar sus timestamps:
Para ordenar fechas, los operadores de comparación funcionan sin más, ya que se convierten automáticamente a número:
La resta te da la diferencia en milisegundos. Divide entre 1000 * 60 * 60 * 24 para obtener los días. La primera vez escribe esa constante completa; con el tiempo vas a reconocer 86_400_000 de un vistazo.
Sumar días a una fecha en JavaScript
No existe un método addDays. Lo habitual es tirar de setDate, setMonth, etc. Lo bueno es que aceptan valores fuera de rango y hacen el "desbordamiento" por ti sin dramas:
Dos detalles que vale la pena destacar:
new Date(date)crea una copia de la fecha.setDatemuta el objeto original, así que conviene copiar siempre antes o terminarás modificando el valor que te pasó quien te llamó.- Llamar a
setDate(35)en un mes de 31 días avanza automáticamente al mes siguiente. Lo mismo ocurre consetMonth(14): salta al año siguiente. Esto hace que la aritmética con fechas sea mucho menos dolorosa de lo que parece.
Para cualquier cosa más compleja —días hábiles, eventos recurrentes, duraciones que tengan en cuenta los meses— mejor tira de una librería (date-fns, Luxon o la futura API Temporal). Más allá de "sumar unos días", inventarte tu propio cálculo de calendario es meterse en un pantano.
Zonas horarias: un baño de realidad
Las zonas horarias son, de lejos, la mayor fuente de bugs con fechas en JavaScript. Estas son las reglas que conviene grabarse a fuego:
- Un
Dateguarda un instante en UTC. La zona horaria solo se aplica al leer sus partes o al formatearlo. - La zona horaria que usan
getHours(),getDate(), etc. es la zona local de la máquina que ejecuta el código. Servidores y navegadores no siempre coinciden. new Date("2026-03-14")(solo fecha) se interpreta como UTC.new Date("2026-03-14T00:00")(con hora, sin zona) se interpreta como local.new Date(2026, 2, 14)(por partes) también es local.
Cuando necesites mostrar una zona horaria concreta, pásale timeZone a Intl.DateTimeFormat:
Un mismo instante, dos formas de verlo. El objeto Date en sí no ha cambiado.
Un pequeño ejemplo práctico
Juntando todo lo anterior, vamos a crear una función que formatea cuánto tiempo hace que ocurrió algo:
Recibes timestamps, devuelves cadenas legibles. Así se ve el 90% del código real con fechas: restas dos instantes, divides entre una unidad, redondeas y formateas.
Lo que te llevas
- Un
Datees un instante en UTC. Las zonas horarias solo aparecen cuando lo lees o lo formateas. - Usa
Date.now()para timestamps ynew Date()cuando trabajes con calendario. toISOString()para almacenamiento y logs;Intl.DateTimeFormatpara mostrar al usuario.- Compara con
getTime()o con</>. Nunca con===. - Los meses empiezan en 0. Ojo con la trampa al parsear cadenas solo-fecha.
- Para matemáticas serias con fechas, tira de una librería.
Siguiente: URLs y query strings
Las fechas suelen terminar metidas en URLs: filtrar por rango, pasar un timestamp como parámetro, etc. Construir y parsear URLs a mano es tan propenso a errores como formatear fechas a mano, y la librería estándar trae un objeto URL que lo resuelve limpio. Eso viene ahora.
Preguntas frecuentes
¿Cómo se obtiene la fecha actual en JavaScript?
Llama a new Date() sin argumentos: te devuelve un objeto Date con el instante exacto en el que se ejecutó el constructor. Si solo necesitas el timestamp numérico (milisegundos desde 1970), tira de Date.now() — es más rápido y no crea un objeto entero.
¿Cómo comparo dos fechas en JavaScript?
Compara los timestamps, no los objetos Date directamente. a.getTime() < b.getTime() funciona, y a < b también porque < convierte las fechas a número. Lo que no vale es a === b: el === compara identidad de objetos, así que dos Date que representan el mismo instante nunca serán estrictamente iguales.
¿Cómo se da formato a una fecha en JavaScript?
Para mostrar la fecha al usuario, usa Intl.DateTimeFormat o date.toLocaleDateString() — gestionan bien los idiomas y las zonas horarias. Para guardarla o mandarla por API, date.toISOString() te da una cadena estándar tipo 2026-03-14T09:30:00.000Z. Evita date.toString() para almacenamiento, porque el formato depende de la configuración regional.
¿Por qué mi fecha en JavaScript sale un día antes?
Casi siempre es cosa de la zona horaria. new Date('2026-03-14') se interpreta como medianoche UTC, pero date.getDate() te devuelve el día en la hora local, que puede ser el día anterior. Usa getUTCDate() si quieres el día en UTC, o construye la fecha con new Date(year, month, day), que desde el principio trabaja en hora local.