TIME

TIME almacena un valor de tiempo en formato HH:MM:SS. A diferencia de lo que su nombre sugiere, no solo representa horas del reloj (00:00:00 a 23:59:59) sino también duraciones y diferencias temporales, con un rango amplio de -838:59:59 a 838:59:59. Ocupa 3 bytes.

Sintaxis

CREATE TABLE nombre_tabla (
    columna TIME NOT NULL
);
 
-- Con precisión de fracciones de segundo (0-6)
columna TIME(3)  -- Milisegundos
columna TIME(6)  -- Microsegundos

Ejemplo básico

CREATE TABLE horarios (
    id INT AUTO_INCREMENT PRIMARY KEY,
    actividad VARCHAR(100) NOT NULL,
    hora_inicio TIME NOT NULL,
    hora_fin TIME NOT NULL,
    duracion TIME
);
 
INSERT INTO horarios (actividad, hora_inicio, hora_fin, duracion) VALUES
('Reunión equipo', '09:00:00', '10:30:00', '01:30:00'),
('Almuerzo', '13:00:00', '14:00:00', '01:00:00'),
('Formación SQL', '15:00:00', '17:00:00', '02:00:00'),
('Guardia nocturna', '22:00:00', '06:00:00', '08:00:00');
 
SELECT * FROM horarios;
idactividadhora_iniciohora_finduracion
1Reunión equipo09:00:0010:30:0001:30:00
2Almuerzo13:00:0014:00:0001:00:00
3Formación SQL15:00:0017:00:0002:00:00
4Guardia nocturna22:00:0006:00:0008:00:00

Obtener la hora actual

La función NOW devuelve fecha y hora; CURTIME() devuelve solo la hora:

SELECT
    CURTIME() AS ahora,
    CURRENT_TIME() AS ahora_alt,
    CURTIME(3) AS con_milisegundos;
ahoraahora_altcon_milisegundos
14:30:4514:30:4514:30:45.123

Extraer partes del tiempo

SELECT
    '14:30:45' AS tiempo,
    HOUR('14:30:45') AS hora,
    MINUTE('14:30:45') AS minuto,
    SECOND('14:30:45') AS segundo;
tiempohoraminutosegundo
14:30:45143045

TIME como duración

TIME puede representar duraciones que exceden las 24 horas:

CREATE TABLE tareas (
    id INT AUTO_INCREMENT PRIMARY KEY,
    nombre VARCHAR(100) NOT NULL,
    tiempo_estimado TIME NOT NULL,
    tiempo_real TIME
);
 
INSERT INTO tareas (nombre, tiempo_estimado, tiempo_real) VALUES
('Migración de BD', '48:00:00', '52:30:00'),
('Deploy producción', '02:00:00', '01:45:00'),
('Code review', '04:00:00', '03:15:00'),
('Testing completo', '24:00:00', '28:00:00');
 
SELECT
    nombre,
    tiempo_estimado,
    tiempo_real,
    TIMEDIFF(tiempo_real, tiempo_estimado) AS diferencia
FROM tareas;
nombretiempo_estimadotiempo_realdiferencia
Migración de BD48:00:0052:30:0004:30:00
Deploy producción02:00:0001:45:00-00:15:00
Code review04:00:0003:15:00-00:45:00
Testing completo24:00:0028:00:0004:00:00

Los valores negativos indican que la tarea se completó antes de lo estimado. Para recuperar solo las tareas completadas tarde, puedes filtrar con WHERE sobre la diferencia.

Aritmética con TIME

ADDTIME y SUBTIME

SELECT
    '09:00:00' AS inicio,
    ADDTIME('09:00:00', '02:30:00') AS mas_dos_y_media,
    SUBTIME('17:00:00', '01:15:00') AS menos_una_y_cuarto;
iniciomas_dos_y_mediamenos_una_y_cuarto
09:00:0011:30:0015:45:00

TIMEDIFF

Calcula la diferencia entre dos tiempos:

SELECT
    hora_inicio,
    hora_fin,
    TIMEDIFF(hora_fin, hora_inicio) AS duracion_calc
FROM horarios
WHERE id IN (1, 2, 3);
hora_iniciohora_finduracion_calc
09:00:0010:30:0001:30:00
13:00:0014:00:0001:00:00
15:00:0017:00:0002:00:00

TIME_TO_SEC y SEC_TO_TIME

Convierte entre TIME y segundos para operaciones aritméticas:

SELECT
    '02:30:00' AS tiempo,
    TIME_TO_SEC('02:30:00') AS en_segundos,
    SEC_TO_TIME(9000) AS de_segundos;
tiempoen_segundosde_segundos
02:30:00900002:30:00
-- Sumar duraciones usando segundos
SELECT
    SEC_TO_TIME(SUM(TIME_TO_SEC(duracion))) AS duracion_total
FROM horarios;
duracion_total
12:30:00

Formatear TIME

SELECT
    TIME_FORMAT('14:30:45', '%H:%i') AS hora_minuto,
    TIME_FORMAT('14:30:45', '%h:%i %p') AS formato_12h,
    TIME_FORMAT('14:30:45', '%H horas %i minutos') AS descriptivo;
hora_minutoformato_12hdescriptivo
14:3002:30 PM14 horas 30 minutos

TIME con fracciones de segundo

CREATE TABLE cronometro (
    id INT AUTO_INCREMENT PRIMARY KEY,
    corredor VARCHAR(50),
    tiempo TIME(3) NOT NULL
);
 
INSERT INTO cronometro (corredor, tiempo) VALUES
('Ana', '00:03:45.123'),
('Luis', '00:03:44.890'),
('Pedro', '00:03:46.001');
 
SELECT corredor, tiempo FROM cronometro ORDER BY tiempo;
corredortiempo
Luis00:03:44.890
Ana00:03:45.123
Pedro00:03:46.001

TIME(3) almacena hasta milisegundos. TIME(6) almacena microsegundos. El almacenamiento adicional es de 1-3 bytes según la precisión. Para columnas de tiempo que nunca deben estar vacías, combina TIME con la restricción NOT NULL.

Valores de TIME desde enteros y cadenas

MySQL acepta varios formatos al insertar un valor TIME:

SELECT
    CAST('14:30:00' AS TIME) AS desde_cadena,
    CAST('1430' AS TIME) AS sin_separadores,
    CAST(143000 AS TIME) AS desde_entero;
desde_cadenasin_separadoresdesde_entero
14:30:0000:14:3014:30:00

Cuidado: '1430' como cadena se interpreta como 14 minutos y 30 segundos (00:14:30), no como 14:30:00. Para evitar ambigüedades, usa siempre el formato completo HH:MM:SS. Cuando necesites registrar también la fecha junto con la hora, usa el tipo DATETIME.

Limpieza

DROP TABLE IF EXISTS horarios;
DROP TABLE IF EXISTS tareas;
DROP TABLE IF EXISTS cronometro;

En el siguiente artículo veremos DATETIME, que combina fecha y hora en un solo valor.

Escrito por Eduardo Lázaro