Command Palette

Search for a command to run...

Creación de Objetos Date en JavaScript

Aprende las diferentes formas de crear objetos Date usando constructores, strings y timestamps. Domina el manejo de fechas desde cero.

Lectura: 10 min
Nivel: Principiante

TL;DR - Resumen rápido

  • Los meses son 0-indexados: enero es 0, no 1 (el error más común)
  • Date.now() es más eficiente que new Date().getTime() para timestamps
  • El formato ISO 8601 es el único confiable para parsear strings entre navegadores
  • JavaScript ajusta automáticamente valores fuera de rango (día 32 → mes siguiente)
  • Validar fechas con isNaN(fecha.getTime()) previene bugs silenciosos con 'Invalid Date'

Introducción a los Objetos Date

El objeto Date en JavaScript representa un único momento en el tiempo, almacenado internamente como milisegundos desde el 1 de enero de 1970 00:00:00 UTC (época Unix). A diferencia de otros lenguajes que tienen tipos separados para fechas y horas, JavaScript usa un solo objeto Date que combina ambos. Esta simplicidad tiene un costo: el objeto Date tiene comportamientos inesperados que causan bugs comunes, especialmente con meses 0-indexados y parseo inconsistente de strings.

JavaScript ofrece cinco formas principales de crear objetos Date, cada una optimizada para diferentes escenarios. Elegir el constructor correcto no solo hace tu código más legible, sino que previene errores sutiles que pueden pasar desapercibidos en testing pero fallar en producción con datos reales de usuarios.

  • Constructor sin argumentos para fecha y hora actual
  • Constructor con valores numéricos (año, mes, día, etc.)
  • Constructor con string de fecha
  • Constructor con timestamp (milisegundos)
  • Constructor copiando otro objeto Date

Base de tiempo Unix

JavaScript almacena las fechas como milisegundos desde el 1 de enero de 1970 a las 00:00:00 UTC. Esta convención, conocida como época Unix, permite representar fechas como números simples, facilitando cálculos y comparaciones.

Constructor sin Argumentos

El constructor sin argumentos crea un objeto Date con la fecha y hora actual del sistema. Este método es ideal para timestamps de eventos, logs, o mostrar la hora actual al usuario. Sin embargo, ten cuidado: la fecha depende del reloj del cliente, que puede estar mal configurado o manipulado. Para aplicaciones críticas (facturación, auditoría), obtén la fecha del servidor, no del cliente.

fecha-actual.js
Loading code...

Cada llamada a new Date() crea un nuevo objeto con un timestamp diferente, incluso si se ejecutan en milisegundos consecutivos. Si necesitas el mismo timestamp en múltiples lugares de tu código, crea el objeto Date una vez y pásalo como referencia, o usa Date.now() para obtener el timestamp numérico que puedes reutilizar.

Date.now() alternativa

Si solo necesitas el timestamp actual en milisegundos, Date.now() es más eficiente que new Date().getTime() porque no crea un objeto Date temporal. Es ideal para medir tiempos de ejecución o generar IDs únicos.

Constructor con Argumentos Numéricos

El constructor Date acepta hasta siete argumentos numéricos para crear una fecha específica. Estos argumentos son, en orden: año, mes, día, hora, minutos, segundos y milisegundos. Es importante entender que el mes es 0-indexado, lo que significa que enero es 0 y diciembre es 11.

constructor-numericos.js
Loading code...

Este constructor es el más explícito y predecible porque no depende de parseo de strings. JavaScript ajusta automáticamente valores fuera de rango: día 32 se convierte en el día 1 del mes siguiente, mes 12 se convierte en enero del año siguiente. Esta característica es útil para cálculos de fechas ("30 días desde hoy"), pero también puede ocultar errores si pasas valores incorrectos.

Advertencia de año

Ten cuidado con los años de dos dígitos. Los años 0-99 se interpretan como 1900-1999. Para años 2000+, siempre usa cuatro dígitos. Por ejemplo, new Date(99, 0, 1) crea 1 de enero de 1999, no 2099.

Argumentos Opcionales

Los argumentos son opcionales de derecha a izquierda: puedes omitir milisegundos, segundos, minutos, hora o día. Los valores predeterminados son 0 para componentes de tiempo (hora, minutos, segundos, ms) y 1 para el día. Esto significa que new Date(2025, 0) crea el 1 de enero de 2025 a medianoche, no una fecha inválida.

argumentos-opcionales.js
Loading code...

Esta flexibilidad es útil cuando trabajas con fechas sin hora específica (reportes diarios, calendarios). Sin embargo, ten cuidado: la fecha se crea en la zona horaria local del sistema, no en UTC. Para fechas UTC, usa los métodos Date.UTC() o el constructor con string ISO 8601.

Constructor con Strings de Fecha

El constructor Date acepta strings de fecha, pero el parseo es notoriamente inconsistente entre navegadores. Antes de ES5, cada navegador implementaba su propio algoritmo de parseo, causando bugs difíciles de reproducir. Desde ES5, el formato ISO 8601 es el único garantizado de funcionar igual en todos los navegadores modernos.

constructor-strings.js
Loading code...

El formato ISO 8601 (YYYY-MM-DDTHH:mm:ss.sssZ) es el más recomendado porque es un estándar internacional y es interpretado de manera consistente por todos los navegadores modernos. Aquí están los formatos de string más confiables:

  • <strong>ISO 8601 completo:</strong> '2025-01-15T14:30:00.000Z' (formato universal recomendado)
  • <strong>ISO 8601 fecha:</strong> '2025-01-15' (sin hora, asume medianoche UTC)
  • <strong>RFC 2822:</strong> 'Wed, 15 Jan 2025 14:30:00 GMT' (usado en APIs y emails)
  • <strong>Timestamp Unix:</strong> Pasar número de milisegundos directamente

Evita formatos ambiguos como 'MM/DD/YYYY' o 'DD/MM/YYYY' porque su interpretación varía según el navegador y la configuración regional del sistema.

Inconsistencia de parseo

Evita strings de fecha en formatos ambiguos como "01/02/2023" porque pueden interpretarse como 1 de febrero o 2 de enero según la configuración regional. Siempre usa formato ISO 8601 (YYYY-MM-DD) para máxima consistencia entre navegadores.

Constructor con Timestamp

Un timestamp es un número entero que representa milisegundos desde el 1 de enero de 1970 00:00:00 UTC. Este formato es universal y libre de ambigüedades sobre zona horaria, formatos regionales, o diferencias entre navegadores. Por esto, los timestamps son el formato preferido para transmitir fechas en APIs REST y almacenar fechas en bases de datos.

constructor-timestamp.js
Loading code...

Los timestamps facilitan operaciones matemáticas: sumar/restar milisegundos es aritmética simple, y comparar fechas es comparar números. El límite de Date es aproximadamente ±8,640,000,000,000,000 ms desde la época Unix, lo que cubre fechas desde el año 271,821 a.C. hasta 275,760 d.C., más que suficiente para aplicaciones modernas.

Constructor Copiando otro Date

Crear una copia de un objeto Date es crucial cuando necesitas modificar una fecha sin afectar el original. A diferencia de tipos primitivos, los objetos Date son mutables: métodos como setDate() o setHours() modifican el objeto existente, no devuelven uno nuevo. Esto causa bugs sutiles cuando pasas objetos Date entre funciones que los modifican inesperadamente.

constructor-copia.js
Loading code...

Al pasar un objeto Date al constructor, obtienes una copia profunda con el mismo timestamp pero independiente del original. Alternativamente, puedes usar new Date(fecha.getTime()) que es funcionalmente idéntico. Crear copias es especialmente importante en funciones puras o cuando trabajas con datos inmutables en React, Redux, o arquitecturas funcionales.

Errores Comunes al Crear Fechas

Al trabajar con objetos Date, hay varios errores comunes que pueden causar bugs difíciles de detectar. Conocer estos patrones problemáticos te ayudará a escribir código más robusto y evitar problemas en producción.

Error: Meses 0-indexados

El error más común con Date es olvidar que los meses son 0-indexados (enero = 0, febrero = 1, ..., diciembre = 11). Este diseño hereda de Java y es inconsistente con los días y años que son 1-indexados. El error es silencioso: no hay excepciones, solo fechas incorrectas que pueden pasar inadvertidas en testing y explotar en producción.

error-mes-indexado.js
Loading code...

Para evitar este error, usa constantes descriptivas (const ENERO = 0, FEBRERO = 1) o preferiblemente el constructor con string ISO 8601 donde los meses son 1-indexados ('2025-01-15'). Muchas librerías modernas como date-fns y Day.js usan meses 1-indexados para evitar esta confusión, pero Date nativo seguirá siendo 0-indexado por compatibilidad.

Error: Años de dos dígitos

Los años de dos dígitos (0-99) se interpretan como 1900-1999, una reliquia del problema del año 2000 (Y2K). Esto significa que new Date(25, 0, 1) crea el 1 de enero de 1925, no 2025. Este comportamiento es por compatibilidad con código legacy, pero causa bugs en código nuevo.

error-ano-dos-digitos.js
Loading code...

Siempre usa años de cuatro dígitos completos. Este problema es especialmente peligroso en aplicaciones de larga vida (sistemas empresariales, aplicaciones financieras) donde el código escrito en 2025 seguirá ejecutándose en 2050+. No asumas que tu código será reescrito pronto.

Error: Fechas inválidas

JavaScript nunca lanza excepciones cuando creas fechas inválidas, en su lugar crea un objeto Date especial con valor interno NaN. Este objeto se muestra como "Invalid Date" pero es técnicamente un objeto Date válido, lo que causa bugs sutiles cuando lo pasas a funciones que no validan. Operaciones matemáticas con fechas inválidas devuelven NaN, propagando el error silenciosamente.

error-invalid-date.js
Loading code...

Siempre valida fechas creadas desde input de usuario o APIs externas usando isNaN(fecha.getTime()). Nota que el constructor con argumentos numéricos ajusta valores fuera de rango (mes 13 → enero del año siguiente) en lugar de crear fechas inválidas, mientras que el constructor con strings crea fechas inválidas cuando el parseo falla. Esto hace que la validación sea crítica al trabajar con strings.

Resumen: Creación de Objetos Date

Conceptos principales:

  • El objeto Date representa milisegundos desde 1970
  • new Date() sin argumentos crea la fecha actual
  • Los meses son 0-indexados (enero = 0, diciembre = 11)
  • El constructor acepta strings, números y otros objetos Date
  • Date.now() devuelve el timestamp actual sin crear objeto

Mejores prácticas:

  • Usa formato ISO 8601 para strings de fecha
  • Siempre usa años de cuatro dígitos
  • Valida fechas con isNaN(date.getTime())
  • Crea copias de objetos Date antes de modificarlos
  • Usa Date.now() para timestamps eficientemente