DATE_ADD
La funcion DATE_ADD suma un intervalo de tiempo a una fecha o un valor datetime y devuelve el resultado. Es la herramienta principal de MySQL para calcular fechas futuras: vencimientos, renovaciones de suscripciones, plazos de entrega o cualquier escenario donde necesites avanzar en el calendario a partir de una fecha conocida.
Sintaxis
DATE_ADD(fecha, INTERVAL expresion unidad)El primer argumento es un valor de tipo DATE, DATETIME o una cadena con formato de fecha válido. La palabra clave INTERVAL introduce la cantidad y la unidad de tiempo que deseas sumar. La expresión puede ser un número entero, un número negativo o una combinación de valores separados por un carácter especial en el caso de intervalos compuestos.
Las unidades simples más habituales son SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER y YEAR. MySQL también admite unidades compuestas como DAY_HOUR, DAY_MINUTE, DAY_SECOND, HOUR_MINUTE, HOUR_SECOND, MINUTE_SECOND y YEAR_MONTH, que permiten sumar dos componentes de tiempo en una sola operación.
Comportamiento básico
El uso más directo consiste en sumar días a una fecha concreta:
SELECT DATE_ADD('2026-03-15', INTERVAL 10 DAY) AS resultado;| resultado |
|---|
| 2026-03-25 |
MySQL suma diez días al 15 de marzo y devuelve el 25 de marzo. El resultado conserva el tipo del argumento de entrada: como pasamos una fecha sin componente horario, la salida también es solo una fecha.
Para sumar meses, la mecánica es la misma:
SELECT DATE_ADD('2026-01-31', INTERVAL 1 MONTH) AS resultado;| resultado |
|---|
| 2026-02-28 |
Observa un detalle importante: enero tiene 31 días, pero febrero de 2026 solo tiene 28. MySQL ajusta automáticamente el resultado al último día del mes destino en lugar de devolver una fecha inválida. Este ajuste ocurre siempre que la fecha resultante caería en un día que no existe en el mes de destino.
Sumar años funciona de forma análoga y también maneja el caso especial de los años bisiestos:
SELECT DATE_ADD('2024-02-29', INTERVAL 1 YEAR) AS resultado;| resultado |
|---|
| 2025-02-28 |
El 29 de febrero de 2024 existe porque es año bisiesto. Al sumar un año, 2025 no es bisiesto, así que MySQL ajusta al 28 de febrero.
Intervalos de tiempo
Cuando el argumento de entrada incluye un componente horario, puedes sumar horas, minutos y segundos:
SELECT DATE_ADD('2026-03-15 09:00:00', INTERVAL 3 HOUR) AS resultado;| resultado |
|---|
| 2026-03-15 12:00:00 |
También puedes sumar minutos y segundos por separado:
SELECT
DATE_ADD('2026-03-15 09:00:00', INTERVAL 45 MINUTE) AS mas_45_min,
DATE_ADD('2026-03-15 09:00:00', INTERVAL 30 SECOND) AS mas_30_seg;| mas_45_min | mas_30_seg |
|---|---|
| 2026-03-15 09:45:00 | 2026-03-15 09:00:30 |
Las unidades WEEK y QUARTER son atajos cómodos. Sumar una semana equivale a sumar 7 días, y sumar un trimestre equivale a sumar 3 meses:
SELECT
DATE_ADD('2026-06-01', INTERVAL 2 WEEK) AS mas_2_semanas,
DATE_ADD('2026-06-01', INTERVAL 1 QUARTER) AS mas_1_trimestre;| mas_2_semanas | mas_1_trimestre |
|---|---|
| 2026-06-15 | 2026-09-01 |
Intervalos compuestos
Los intervalos compuestos permiten sumar dos componentes de tiempo con una sola llamada. La expresión se escribe como una cadena donde los valores se separan por un espacio, dos puntos o guion, dependiendo de la unidad:
SELECT DATE_ADD('2026-03-15 09:00:00', INTERVAL '2:30' HOUR_MINUTE) AS resultado;| resultado |
|---|
| 2026-03-15 11:30:00 |
Aquí sumamos 2 horas y 30 minutos en una sola operación. Otros intervalos compuestos frecuentes:
SELECT
DATE_ADD('2026-03-15 09:00:00', INTERVAL '1 12' DAY_HOUR) AS dia_hora,
DATE_ADD('2026-01-15', INTERVAL '2-6' YEAR_MONTH) AS anio_mes,
DATE_ADD('2026-03-15 09:00:00', INTERVAL '1:30:00' HOUR_SECOND) AS hora_seg;| dia_hora | anio_mes | hora_seg |
|---|---|---|
| 2026-03-16 21:00:00 | 2028-07-15 | 2026-03-15 10:30:00 |
El intervalo DAY_HOUR usa un espacio como separador, YEAR_MONTH usa un guion y HOUR_SECOND usa dos puntos. La documentación de MySQL especifica el formato exacto para cada tipo compuesto.
Caso práctico: fechas de vencimiento de pedidos
Imagina una tabla pedidos donde cada registro tiene una fecha de creación. Necesitas calcular la fecha límite de entrega (7 días después) y la fecha de vencimiento de la garantía (2 años después):
SELECT
id,
fecha_creacion,
DATE_ADD(fecha_creacion, INTERVAL 7 DAY) AS fecha_limite_entrega,
DATE_ADD(fecha_creacion, INTERVAL 2 YEAR) AS fin_garantia
FROM pedidos
ORDER BY fecha_creacion DESC
LIMIT 5;| id | fecha_creacion | fecha_limite_entrega | fin_garantia |
|---|---|---|---|
| 1024 | 2026-02-10 | 2026-02-17 | 2028-02-10 |
| 1023 | 2026-02-08 | 2026-02-15 | 2028-02-08 |
| 1022 | 2026-02-05 | 2026-02-12 | 2028-02-05 |
| 1021 | 2026-02-01 | 2026-02-08 | 2028-02-01 |
| 1020 | 2026-01-28 | 2026-02-04 | 2028-01-28 |
Cada columna calculada aplica un intervalo distinto a la misma fecha de origen. Esto es muy habitual en sistemas de e-commerce y gestión de pedidos.
Caso práctico: renovación de suscripciones
En un sistema de suscripciones, necesitas calcular cuándo se renueva cada plan según su tipo (mensual, trimestral o anual):
SELECT
cliente_id,
plan,
fecha_inicio,
CASE plan
WHEN 'mensual' THEN DATE_ADD(fecha_inicio, INTERVAL 1 MONTH)
WHEN 'trimestral' THEN DATE_ADD(fecha_inicio, INTERVAL 1 QUARTER)
WHEN 'anual' THEN DATE_ADD(fecha_inicio, INTERVAL 1 YEAR)
END AS fecha_renovacion
FROM suscripciones
WHERE activa = 1
ORDER BY fecha_renovacion
LIMIT 5;| cliente_id | plan | fecha_inicio | fecha_renovacion |
|---|---|---|---|
| 45 | mensual | 2026-01-20 | 2026-02-20 |
| 112 | mensual | 2026-01-25 | 2026-02-25 |
| 78 | trimestral | 2025-12-01 | 2026-03-01 |
| 203 | anual | 2025-04-15 | 2026-04-15 |
| 89 | anual | 2025-06-01 | 2026-06-01 |
Combinar DATE_ADD con CASE permite aplicar lógica condicional de fechas que refleja las reglas de negocio de cada tipo de plan.
Caso práctico: filtrar registros por ventana temporal
Un uso muy frecuente de DATE_ADD es construir ventanas de tiempo en la cláusula WHERE. Por ejemplo, encontrar los pedidos cuya entrega está próxima a vencer (dentro de los próximos 3 días):
SELECT id, cliente_id, fecha_entrega_estimada
FROM pedidos
WHERE fecha_entrega_estimada BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 3 DAY)
AND estado = 'en_transito'
ORDER BY fecha_entrega_estimada;Esta consulta selecciona solo los pedidos en tránsito cuya entrega se espera entre hoy y dentro de tres días, lo cual es útil para paneles de control logísticos.
Manejo de NULL
Cuando cualquiera de los argumentos es NULL, DATE_ADD devuelve NULL sin generar un error:
SELECT
DATE_ADD(NULL, INTERVAL 5 DAY) AS fecha_nula,
DATE_ADD('2026-03-15', INTERVAL NULL DAY) AS intervalo_nulo;| fecha_nula | intervalo_nulo |
|---|---|
| NULL | NULL |
Si trabajas con columnas que pueden contener valores nulos, considera usar COALESCE o IFNULL para proporcionar un valor por defecto antes de aplicar la función:
SELECT
nombre,
DATE_ADD(COALESCE(fecha_ultimo_pedido, fecha_registro), INTERVAL 30 DAY) AS siguiente_recordatorio
FROM clientes;Combinación con otras funciones
DATE_ADD se combina frecuentemente con NOW() y CURDATE() para cálculos relativos al momento actual:
SELECT
DATE_ADD(NOW(), INTERVAL 1 HOUR) AS dentro_de_una_hora,
DATE_ADD(CURDATE(), INTERVAL 90 DAY) AS dentro_de_90_dias,
DATE_FORMAT(DATE_ADD(NOW(), INTERVAL 6 MONTH), '%d/%m/%Y') AS semestre_formateado;| dentro_de_una_hora | dentro_de_90_dias | semestre_formateado |
|---|---|---|
| 2026-02-14 16:30:00 | 2026-05-15 | 14/08/2026 |
También puedes encadenar varias llamadas a DATE_ADD cuando necesitas sumar intervalos de distinto tipo:
SELECT DATE_ADD(DATE_ADD('2026-01-15', INTERVAL 2 MONTH), INTERVAL 10 DAY) AS resultado;| resultado |
|---|
| 2026-03-25 |
Esto suma primero 2 meses (llegando al 15 de marzo) y luego 10 días. El operador + con INTERVAL es una alternativa equivalente que puede ser más legible en estos casos:
SELECT '2026-01-15' + INTERVAL 2 MONTH + INTERVAL 10 DAY AS resultado;| resultado |
|---|
| 2026-03-25 |
Ambas formas producen exactamente el mismo resultado.
En el siguiente artículo veremos DATE_SUB para restar intervalos de una fecha.
Escrito por Eduardo Lázaro
