DATETIME

DATETIME almacena fecha y hora en un solo valor, con formato YYYY-MM-DD HH:MM:SS. Ocupa 5 bytes (más 0-3 bytes si usas fracciones de segundo) y soporta un rango desde 1000-01-01 00:00:00 hasta 9999-12-31 23:59:59. A diferencia de TIMESTAMP, no se convierte a UTC al almacenarse, lo que lo hace ideal para fechas absolutas que no dependen de la zona horaria.

Sintaxis

CREATE TABLE nombre_tabla (
    columna DATETIME NOT NULL,
    columna_precisa DATETIME(6)  -- Con microsegundos
);

Ejemplo básico

CREATE TABLE reservas (
    id INT AUTO_INCREMENT PRIMARY KEY,
    sala VARCHAR(50) NOT NULL,
    responsable VARCHAR(100) NOT NULL,
    inicio DATETIME NOT NULL,
    fin DATETIME NOT NULL
);
 
INSERT INTO reservas (sala, responsable, inicio, fin) VALUES
('Sala A', 'María', '2026-02-14 09:00:00', '2026-02-14 10:30:00'),
('Sala B', 'Carlos', '2026-02-14 11:00:00', '2026-02-14 12:00:00'),
('Sala A', 'Ana', '2026-02-14 14:00:00', '2026-02-14 16:00:00'),
('Sala C', 'Pedro', '2026-02-15 09:00:00', '2026-02-15 11:00:00');
 
SELECT * FROM reservas;
idsalaresponsableiniciofin
1Sala AMaría2026-02-14 09:00:002026-02-14 10:30:00
2Sala BCarlos2026-02-14 11:00:002026-02-14 12:00:00
3Sala AAna2026-02-14 14:00:002026-02-14 16:00:00
4Sala CPedro2026-02-15 09:00:002026-02-15 11:00:00

DATETIME en tienda_mysql

La tabla pedidos usa DATETIME para la fecha del pedido:

SELECT id, cliente_id, fecha_pedido, estado, total
FROM pedidos
ORDER BY fecha_pedido DESC
LIMIT 5;
idcliente_idfecha_pedidoestadototal
25192026-01-08 14:20:00cancelado149.99
24182026-01-05 12:00:00pendiente29.99
23172026-01-03 10:45:00pendiente64.98
22162025-12-28 15:30:00procesando399.00
2162025-12-22 09:15:00enviado249.99
-- Pedidos del mes de noviembre 2025
SELECT id, fecha_pedido, total
FROM pedidos
WHERE fecha_pedido >= '2025-11-01' AND fecha_pedido < '2025-12-01';
idfecha_pedidototal
72025-11-05 13:30:00179.97
82025-11-10 09:00:00259.98
92025-11-15 17:20:001399.00
102025-11-18 12:00:00129.99
112025-11-22 08:45:00599.99
122025-11-25 15:10:0084.97

NOW()

NOW() devuelve la fecha y hora actual como DATETIME:

SELECT
    NOW() AS ahora,
    NOW(3) AS con_milisegundos,
    DATE(NOW()) AS solo_fecha,
    TIME(NOW()) AS solo_hora;
ahoracon_milisegundossolo_fechasolo_hora
2026-02-14 14:30:002026-02-14 14:30:00.1232026-02-1414:30:00

DATE() y TIME() extraen la parte de fecha y hora respectivamente.

Extraer componentes

SELECT
    fecha_pedido,
    YEAR(fecha_pedido) AS anio,
    MONTH(fecha_pedido) AS mes,
    DAY(fecha_pedido) AS dia,
    HOUR(fecha_pedido) AS hora,
    MINUTE(fecha_pedido) AS minuto
FROM pedidos
WHERE id = 1;
fecha_pedidoaniomesdiahoraminuto
2025-10-05 09:30:002025105930

Aritmética con DATETIME

SELECT
    NOW() AS ahora,
    DATE_ADD(NOW(), INTERVAL 2 HOUR) AS en_dos_horas,
    DATE_ADD(NOW(), INTERVAL 30 MINUTE) AS en_media_hora,
    DATE_SUB(NOW(), INTERVAL 1 DAY) AS ayer_misma_hora;
ahoraen_dos_horasen_media_horaayer_misma_hora
2026-02-14 14:30:002026-02-14 16:30:002026-02-14 15:00:002026-02-13 14:30:00

Diferencia entre dos DATETIME

SELECT
    TIMESTAMPDIFF(HOUR, '2026-02-14 09:00:00', '2026-02-14 17:30:00') AS horas,
    TIMESTAMPDIFF(MINUTE, '2026-02-14 09:00:00', '2026-02-14 17:30:00') AS minutos,
    TIMEDIFF('2026-02-14 17:30:00', '2026-02-14 09:00:00') AS diferencia;
horasminutosdiferencia
851008:30:00

Formatear DATETIME

SELECT
    fecha_pedido,
    DATE_FORMAT(fecha_pedido, '%d/%m/%Y %H:%i') AS formato_europeo,
    DATE_FORMAT(fecha_pedido, '%W, %d de %M de %Y') AS formato_largo,
    DATE_FORMAT(fecha_pedido, '%h:%i %p') AS hora_12h
FROM pedidos
WHERE id = 1;
fecha_pedidoformato_europeoformato_largohora_12h
2025-10-05 09:30:0005/10/2025 09:30Sunday, 05 de October de 202509:30 AM

DATETIME vs TIMESTAMP

CaracterísticaDATETIMETIMESTAMP
Rango1000-01-01 a 9999-12-311970-01-01 a 2038-01-19
Almacenamiento5 bytes4 bytes
Zona horariaAlmacena literalConvierte a/desde UTC
DEFAULT CURRENT_TIMESTAMPSoportadoSoportado
ON UPDATE CURRENT_TIMESTAMPSoportadoSoportado

Usa DATETIME cuando la fecha debe ser exactamente la que se insertó, sin importar la zona horaria del servidor (fechas de nacimiento, eventos fijos). Usa TIMESTAMP cuando necesitas que la fecha se adapte a la zona horaria del usuario (logs, auditoría, contenido generado).

DATETIME con fracciones de segundo

CREATE TABLE logs (
    id INT AUTO_INCREMENT PRIMARY KEY,
    evento VARCHAR(100),
    timestamp_preciso DATETIME(6) NOT NULL DEFAULT NOW(6)
);
 
INSERT INTO logs (evento) VALUES ('inicio'), ('proceso'), ('fin');
 
SELECT id, evento, timestamp_preciso FROM logs;
ideventotimestamp_preciso
1inicio2026-02-14 14:30:00.123456
2proceso2026-02-14 14:30:00.234567
3fin2026-02-14 14:30:00.345678
PrecisiónBytes adicionales
DATETIME(0)0
DATETIME(1-2)1
DATETIME(3-4)2
DATETIME(5-6)3

Convertir cadenas a DATETIME

SELECT
    STR_TO_DATE('14/02/2026 09:30', '%d/%m/%Y %H:%i') AS desde_cadena,
    CAST('2026-02-14 09:30:00' AS DATETIME) AS con_cast;
desde_cadenacon_cast
2026-02-14 09:30:002026-02-14 09:30:00

Consultas comunes

-- Pedidos de hoy
SELECT * FROM pedidos WHERE DATE(fecha_pedido) = CURDATE();
 
-- Pedidos de la última hora
SELECT * FROM pedidos WHERE fecha_pedido >= DATE_SUB(NOW(), INTERVAL 1 HOUR);
 
-- Agrupar por fecha (sin hora)
SELECT
    DATE(fecha_pedido) AS fecha,
    COUNT(*) AS num_pedidos,
    SUM(total) AS venta_diaria
FROM pedidos
GROUP BY DATE(fecha_pedido)
ORDER BY fecha DESC
LIMIT 5;
fechanum_pedidosventa_diaria
2026-01-081149.99
2026-01-05129.99
2026-01-03164.98
2025-12-281399.00
2025-12-221249.99

Limpieza

DROP TABLE IF EXISTS reservas;
DROP TABLE IF EXISTS logs;

En el siguiente artículo veremos TIMESTAMP, similar a DATETIME pero con conversión automática de zona horaria.

Escrito por Eduardo Lázaro