ADDTIME
La funcion ADDTIME suma un valor de tiempo a una expresión de tipo DATETIME o TIME y devuelve el resultado. A diferencia de DATE_ADD, que trabaja con intervalos nombrados como DAY o HOUR, ADDTIME recibe directamente un valor en formato de tiempo (HH:MM:SS o HH:MM:SS.fraccion), lo que la convierte en la opción natural cuando ya tienes la duración expresada como un valor de tiempo.
Sintaxis
ADDTIME(expr1, expr2)El primer argumento expr1 es un valor de tipo DATETIME o TIME. El segundo argumento expr2 es un valor de tipo TIME que representa la duración a sumar. Si expr2 es negativo, ADDTIME efectúa una resta en lugar de una suma.
El formato completo de expr2 es D HH:MM:SS.fraccion, donde D representa días. Sin embargo, en la práctica se usan con mayor frecuencia los formatos HH:MM:SS o simplemente un número de segundos.
Comportamiento básico
Sumar dos horas y treinta minutos a un valor datetime:
SELECT ADDTIME('2026-03-15 09:00:00', '02:30:00') AS resultado;| resultado |
|---|
| 2026-03-15 11:30:00 |
MySQL interpreta el segundo argumento como 2 horas, 30 minutos y 0 segundos, y lo suma al datetime proporcionado. El resultado incluye el componente de fecha porque el primer argumento es un datetime completo.
Cuando ambos argumentos son valores de tipo TIME, el resultado también es un valor TIME:
SELECT ADDTIME('10:30:00', '01:45:30') AS resultado;| resultado |
|---|
| 12:15:30 |
Esto es útil para calcular la hora de finalización de un turno, una reunión o cualquier evento con duración conocida.
ADDTIME también acepta fracciones de segundo con hasta 6 decimales de precisión (microsegundos):
SELECT ADDTIME('09:00:00.000000', '00:00:01.500000') AS resultado;| resultado |
|---|
| 09:00:01.500000 |
Diferencia con DATE_ADD
Aunque ADDTIME y DATE_ADD pueden lograr resultados similares, cada una tiene su nicho. DATE_ADD trabaja con intervalos nombrados y es más expresiva cuando sumas unidades como meses, años o semanas. ADDTIME trabaja directamente con valores de tiempo y resulta más práctica cuando la duración ya está almacenada en formato TIME en tu base de datos.
Estas dos consultas producen el mismo resultado:
SELECT
DATE_ADD('2026-03-15 09:00:00', INTERVAL 150 MINUTE) AS con_date_add,
ADDTIME('2026-03-15 09:00:00', '02:30:00') AS con_addtime;| con_date_add | con_addtime |
|---|---|
| 2026-03-15 11:30:00 | 2026-03-15 11:30:00 |
La diferencia principal es la forma en que expresas la duración. Con DATE_ADD especificas 150 minutos; con ADDTIME especificas directamente 2 horas y 30 minutos en formato de tiempo. Elige la que haga tu consulta más legible según el contexto.
Caso práctico: calcular hora de finalización de turnos
Imagina una tabla turnos que registra la hora de entrada de cada empleado y la duración planificada de su turno:
SELECT
e.nombre,
t.hora_entrada,
t.duracion,
ADDTIME(t.hora_entrada, t.duracion) AS hora_salida
FROM turnos t
JOIN empleados e ON t.empleado_id = e.id
WHERE t.fecha = CURDATE()
ORDER BY t.hora_entrada;| nombre | hora_entrada | duracion | hora_salida |
|---|---|---|---|
| María García | 06:00:00 | 08:00:00 | 14:00:00 |
| Carlos López | 08:30:00 | 08:00:00 | 16:30:00 |
| Ana Martínez | 14:00:00 | 06:00:00 | 20:00:00 |
| Pedro Ruiz | 16:00:00 | 08:00:00 | 24:00:00 |
| Lucía Fernández | 22:00:00 | 08:00:00 | 30:00:00 |
Observa que cuando la hora de salida supera la medianoche, MySQL muestra valores superiores a 24:00:00 en el tipo TIME. El tipo TIME de MySQL admite rangos desde -838:59:59 hasta 838:59:59, por lo que estos valores son válidos. Si necesitas expresar el resultado como un datetime concreto del día siguiente, tendrías que combinar con la fecha del turno.
Caso práctico: tiempos de preparación de pedidos
En un sistema de logística, cada pedido tiene una hora de recepción y un tiempo estimado de preparación que varía según la complejidad:
SELECT
p.id AS pedido_id,
p.hora_recepcion,
p.tiempo_preparacion,
ADDTIME(p.hora_recepcion, p.tiempo_preparacion) AS hora_listo,
CASE
WHEN ADDTIME(p.hora_recepcion, p.tiempo_preparacion) > CURTIME()
THEN 'En preparación'
ELSE 'Listo'
END AS estado
FROM pedidos_almacen p
WHERE p.fecha = CURDATE()
ORDER BY hora_listo;| pedido_id | hora_recepcion | tiempo_preparacion | hora_listo | estado |
|---|---|---|---|---|
| 501 | 08:15:00 | 00:45:00 | 09:00:00 | Listo |
| 502 | 09:00:00 | 01:30:00 | 10:30:00 | Listo |
| 503 | 10:20:00 | 02:00:00 | 12:20:00 | Listo |
| 504 | 13:00:00 | 01:15:00 | 14:15:00 | En preparación |
| 505 | 14:30:00 | 03:00:00 | 17:30:00 | En preparación |
La combinación de ADDTIME con CASE permite clasificar cada pedido según si su hora estimada de finalización ya pasó o no.
Caso práctico: restar tiempo con valores negativos
ADDTIME también sirve para restar tiempo si proporcionas un valor negativo como segundo argumento:
SELECT
ADDTIME('2026-03-15 12:00:00', '-01:30:00') AS menos_hora_media,
ADDTIME('17:00:00', '-02:00:00') AS menos_dos_horas;| menos_hora_media | menos_dos_horas |
|---|---|
| 2026-03-15 10:30:00 | 15:00:00 |
Esto es equivalente a usar la función SUBTIME, que existe específicamente para restar tiempo. Sin embargo, ADDTIME con valores negativos es frecuente cuando el signo de la duración proviene de un cálculo previo.
Manejo de NULL
Si cualquiera de los dos argumentos es NULL, ADDTIME devuelve NULL:
SELECT
ADDTIME(NULL, '02:00:00') AS primer_nulo,
ADDTIME('09:00:00', NULL) AS segundo_nulo;| primer_nulo | segundo_nulo |
|---|---|
| NULL | NULL |
Cuando trabajes con columnas que puedan contener NULL, protege la consulta con COALESCE para evitar que un valor nulo se propague al resultado:
SELECT
nombre,
ADDTIME(
COALESCE(hora_entrada, '09:00:00'),
COALESCE(duracion_turno, '08:00:00')
) AS hora_salida_estimada
FROM empleados;Combinación con otras funciones
ADDTIME se complementa bien con NOW() y CURTIME() para cálculos relativos al momento actual:
SELECT
ADDTIME(NOW(), '04:00:00') AS dentro_de_4_horas,
ADDTIME(CURTIME(), '00:30:00') AS dentro_de_30_minutos;| dentro_de_4_horas | dentro_de_30_minutos |
|---|---|
| 2026-02-14 19:30:00 | 15:30:00 |
También puedes combinarla con SEC_TO_TIME cuando la duración está almacenada en segundos en lugar de en formato TIME:
SELECT
t.nombre_tarea,
t.hora_inicio,
t.duracion_segundos,
ADDTIME(t.hora_inicio, SEC_TO_TIME(t.duracion_segundos)) AS hora_fin
FROM tareas t
WHERE t.fecha = CURDATE();| nombre_tarea | hora_inicio | duracion_segundos | hora_fin |
|---|---|---|---|
| Backup BD | 02:00:00 | 5400 | 03:30:00 |
| Reindexación | 04:00:00 | 7200 | 06:00:00 |
| Envío reportes | 08:00:00 | 900 | 08:15:00 |
SEC_TO_TIME convierte los segundos almacenados como entero al formato TIME que ADDTIME necesita, creando una cadena de funciones que transforma datos crudos en información útil.
En el siguiente artículo veremos DATEDIFF para calcular la diferencia en días entre dos fechas.
Escrito por Eduardo Lázaro
