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;
positivonegativo
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_datediffcon_timediff
104: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;
nombreinicio_sesionfin_sesionduracion
María García2026-02-14 08:05:122026-02-14 17:48:3009:43:18
Carlos López2026-02-14 09:12:452026-02-14 18:30:0009:17:15
Ana Martínez2026-02-14 07:55:002026-02-14 16:10:2208:15:22
Pedro Ruiz2026-02-14 10:30:002026-02-14 15:45:1005:15:10
Lucía Fernández2026-02-14 14:00:002026-02-14 18:20:0004: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;
nombrehora_entradahora_salidahoras_trabajadashoras_extra
Ana Martínez08:00:0016:15:0008:15:0000:15:00
Carlos López07:45:0017:30:0009:45:0001:45:00
Elena Ruiz09:00:0017:00:0008:00:0000:00:00
María García08:30:0015:00:0006:30:0000:00:00
Pedro Navarro07:00:0018:00:0011:00:0003: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_idprioridadfecha_creacionfecha_primera_respuestatiempo_respuesta
3401alta2026-02-10 09:15:002026-02-10 09:42:0000:27:00
3415alta2026-02-12 14:30:002026-02-12 15:05:0000:35:00
3398media2026-02-09 11:00:002026-02-09 14:22:0003:22:00
3420media2026-02-13 16:45:002026-02-14 09:10:0016:25:00
3395baja2026-02-08 08:30:002026-02-09 10:15:0025:45:00
3405baja2026-02-11 15:00:002026-02-13 11:30:0044: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_nulosegundo_nulo
NULLNULL

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;
idduracion_segundosduracion_horas
501351009.75
502294008.17
503252007.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