TIMEDIFF
La funcion TIMEDIFF calcula la diferencia entre dos expresiones de tiempo y devuelve el resultado como un valor TIME. A diferencia de DATEDIFF, que solo trabaja con días enteros, TIMEDIFF preserva la precisión hasta los segundos (e incluso microsegundos), lo que la convierte en la herramienta adecuada para medir duraciones exactas entre dos momentos.
Sintaxis
TIMEDIFF(expr1, expr2)Ambos argumentos deben ser del mismo tipo: o ambos DATETIME, o ambos TIME. No puedes mezclar un DATETIME con un TIME. El resultado es expr1 - expr2 expresado como un valor de tipo TIME. El rango del tipo TIME en MySQL va de -838:59:59 a 838:59:59, lo que equivale aproximadamente a 34 días con 22 horas. Si la diferencia excede este rango, MySQL truncará el resultado.
Comportamiento básico
Calcular la diferencia entre dos valores datetime:
SELECT TIMEDIFF('2026-03-15 17:30:00', '2026-03-15 09:00:00') AS diferencia;| diferencia |
|---|
| 08:30:00 |
El resultado indica 8 horas y 30 minutos de diferencia. Al igual que DATEDIFF, el orden de los argumentos determina el signo del resultado:
SELECT
TIMEDIFF('2026-03-15 17:30:00', '2026-03-15 09:00:00') AS positivo,
TIMEDIFF('2026-03-15 09:00:00', '2026-03-15 17:30:00') AS negativo;| positivo | negativo |
|---|---|
| 08:30:00 | -08:30:00 |
El resultado negativo indica que el primer argumento es anterior al segundo. Con valores TIME puros, la mecánica es la misma:
SELECT TIMEDIFF('18:45:00', '14:20:30') AS diferencia;| diferencia |
|---|
| 04:24:30 |
La diferencia incluye horas, minutos y segundos. TIMEDIFF también maneja microsegundos si los valores de entrada los incluyen:
SELECT TIMEDIFF('10:30:45.500000', '10:30:44.200000') AS diferencia;| diferencia |
|---|
| 00:00:01.300000 |
Diferencia con DATEDIFF
Es importante entender cuándo usar cada función. DATEDIFF devuelve solo días enteros e ignora la hora. TIMEDIFF devuelve la diferencia exacta incluyendo horas, minutos y segundos. Veamos la diferencia con un ejemplo claro:
SELECT
DATEDIFF('2026-03-16 02:00:00', '2026-03-15 22:00:00') AS con_datediff,
TIMEDIFF('2026-03-16 02:00:00', '2026-03-15 22:00:00') AS con_timediff;| con_datediff | con_timediff |
|---|---|
| 1 | 04:00:00 |
DATEDIFF informa 1 día de diferencia (16 de marzo menos 15 de marzo), mientras que TIMEDIFF revela que la diferencia real es de solo 4 horas. Dependiendo de lo que necesites, una u otra será más apropiada.
Caso práctico: duración de sesiones de usuario
En aplicaciones web, es habitual registrar la hora de inicio y fin de cada sesión. TIMEDIFF permite calcular cuánto tiempo estuvo conectado cada usuario:
SELECT
u.nombre,
s.inicio_sesion,
s.fin_sesion,
TIMEDIFF(s.fin_sesion, s.inicio_sesion) AS duracion
FROM sesiones s
JOIN usuarios u ON s.usuario_id = u.id
WHERE s.fecha = '2026-02-14'
ORDER BY duracion DESC
LIMIT 5;| nombre | inicio_sesion | fin_sesion | duracion |
|---|---|---|---|
| María García | 2026-02-14 08:05:12 | 2026-02-14 17:48:30 | 09:43:18 |
| Carlos López | 2026-02-14 09:12:45 | 2026-02-14 18:30:00 | 09:17:15 |
| Ana Martínez | 2026-02-14 07:55:00 | 2026-02-14 16:10:22 | 08:15:22 |
| Pedro Ruiz | 2026-02-14 10:30:00 | 2026-02-14 15:45:10 | 05:15:10 |
| Lucía Fernández | 2026-02-14 14:00:00 | 2026-02-14 18:20:00 | 04:20:00 |
Para obtener la duración promedio de las sesiones, puedes combinar TIMEDIFF con TIME_TO_SEC y SEC_TO_TIME, ya que MySQL no permite promediar directamente valores TIME:
SELECT
SEC_TO_TIME(AVG(TIME_TO_SEC(TIMEDIFF(fin_sesion, inicio_sesion)))) AS duracion_promedio
FROM sesiones
WHERE fecha = '2026-02-14';| duracion_promedio |
|---|
| 07:22:13 |
La cadena TIME_TO_SEC convierte a segundos, AVG promedia, y SEC_TO_TIME reconvierte a formato legible.
Caso práctico: horas trabajadas por empleado
Para un sistema de control de asistencia donde se registran las marcaciones de entrada y salida:
SELECT
e.nombre,
a.hora_entrada,
a.hora_salida,
TIMEDIFF(a.hora_salida, a.hora_entrada) AS horas_trabajadas,
CASE
WHEN TIMEDIFF(a.hora_salida, a.hora_entrada) > '08:00:00'
THEN TIMEDIFF(TIMEDIFF(a.hora_salida, a.hora_entrada), '08:00:00')
ELSE '00:00:00'
END AS horas_extra
FROM asistencia a
JOIN empleados e ON a.empleado_id = e.id
WHERE a.fecha = '2026-02-14'
ORDER BY e.nombre;| nombre | hora_entrada | hora_salida | horas_trabajadas | horas_extra |
|---|---|---|---|---|
| Ana Martínez | 08:00:00 | 16:15:00 | 08:15:00 | 00:15:00 |
| Carlos López | 07:45:00 | 17:30:00 | 09:45:00 | 01:45:00 |
| Elena Ruiz | 09:00:00 | 17:00:00 | 08:00:00 | 00:00:00 |
| María García | 08:30:00 | 15:00:00 | 06:30:00 | 00:00:00 |
| Pedro Navarro | 07:00:00 | 18:00:00 | 11:00:00 | 03:00:00 |
Observa cómo se usa TIMEDIFF anidado en el CASE: primero calcula las horas trabajadas totales, y luego resta las 8 horas de jornada estándar para obtener las horas extra. Si el resultado sería negativo (menos de 8 horas), se devuelve 00:00:00.
Caso práctico: tiempo de respuesta de soporte
Medir el tiempo que tarda el equipo de soporte en responder a los tickets es un indicador clave de calidad:
SELECT
t.id AS ticket_id,
t.prioridad,
t.fecha_creacion,
t.fecha_primera_respuesta,
TIMEDIFF(t.fecha_primera_respuesta, t.fecha_creacion) AS tiempo_respuesta
FROM tickets_soporte t
WHERE t.fecha_primera_respuesta IS NOT NULL
AND t.fecha_creacion >= '2026-02-01'
ORDER BY t.prioridad, tiempo_respuesta DESC
LIMIT 6;| ticket_id | prioridad | fecha_creacion | fecha_primera_respuesta | tiempo_respuesta |
|---|---|---|---|---|
| 3401 | alta | 2026-02-10 09:15:00 | 2026-02-10 09:42:00 | 00:27:00 |
| 3415 | alta | 2026-02-12 14:30:00 | 2026-02-12 15:05:00 | 00:35:00 |
| 3398 | media | 2026-02-09 11:00:00 | 2026-02-09 14:22:00 | 03:22:00 |
| 3420 | media | 2026-02-13 16:45:00 | 2026-02-14 09:10:00 | 16:25:00 |
| 3395 | baja | 2026-02-08 08:30:00 | 2026-02-09 10:15:00 | 25:45:00 |
| 3405 | baja | 2026-02-11 15:00:00 | 2026-02-13 11:30:00 | 44:30:00 |
Los tickets de prioridad alta se responden en menos de una hora, los de prioridad media en unas pocas horas y los de baja prioridad pueden tardar más de un día. Nota que TIMEDIFF muestra valores superiores a 24 horas (como 44:30:00) porque el tipo TIME lo permite.
Manejo de NULL
TIMEDIFF devuelve NULL si cualquiera de los argumentos es NULL:
SELECT
TIMEDIFF(NULL, '09:00:00') AS primero_nulo,
TIMEDIFF('17:00:00', NULL) AS segundo_nulo;| primero_nulo | segundo_nulo |
|---|---|
| NULL | NULL |
Esto es relevante en escenarios donde la hora de salida o la fecha de respuesta aún no se ha registrado. Puedes filtrar estos registros o manejarlos con IFNULL:
SELECT
nombre,
TIMEDIFF(
IFNULL(hora_salida, CURTIME()),
hora_entrada
) AS tiempo_transcurrido
FROM asistencia
WHERE fecha = CURDATE();Esta consulta usa la hora actual como hora de salida para los empleados que aún no han marcado salida, permitiendo ver cuánto tiempo llevan trabajando.
Combinación con otras funciones
TIMEDIFF se combina bien con TIME_TO_SEC cuando necesitas el resultado en segundos para hacer cálculos numéricos:
SELECT
id,
TIME_TO_SEC(TIMEDIFF(fin_sesion, inicio_sesion)) AS duracion_segundos,
ROUND(TIME_TO_SEC(TIMEDIFF(fin_sesion, inicio_sesion)) / 3600, 2) AS duracion_horas
FROM sesiones
WHERE fecha = CURDATE()
LIMIT 3;| id | duracion_segundos | duracion_horas |
|---|---|---|
| 501 | 35100 | 9.75 |
| 502 | 29400 | 8.17 |
| 503 | 25200 | 7.00 |
La conversión a segundos permite usar funciones de agregación numéricas estándar como SUM, AVG, MIN y MAX sin las limitaciones del tipo TIME. Si necesitas diferencias en unidades más grandes como días, meses o años, la función TIMESTAMPDIFF que veremos próximamente será más apropiada.
En el siguiente artículo veremos TIMESTAMPDIFF para calcular diferencias en unidades específicas.
Escrito por Eduardo Lázaro
