Insertar fechas en MySQL

El tipo DATE en MySQL almacena fechas en formato YYYY-MM-DD (año-mes-día). Aunque MySQL acepta varios formatos de entrada, internamente siempre las almacena en este formato estándar. Entender cómo funciona la inserción de fechas evita errores frecuentes y datos incorrectos.

Formato estándar

La forma más directa y recomendada es usar el formato YYYY-MM-DD como cadena de texto:

INSERT INTO empleados (nombre, apellidos, email, puesto, salario, fecha_contratacion)
VALUES ('Lucía', 'Ramos Gil', 'lucia.ramos@tienda.com', 'Becaria', 18000, '2025-09-15');

La fecha '2025-09-15' representa el 15 de septiembre de 2025. MySQL la interpreta correctamente porque sigue el formato estándar ISO 8601.

Formatos alternativos aceptados

MySQL es bastante flexible y acepta otros formatos para las fechas:

-- Con barras en lugar de guiones
INSERT INTO empleados (nombre, apellidos, email, puesto, salario, fecha_contratacion)
VALUES ('Ejemplo 1', 'Test', 'test1@tienda.com', 'Test', 20000, '2025/09/15');
 
-- Sin separadores (YYYYMMDD)
INSERT INTO empleados (nombre, apellidos, email, puesto, salario, fecha_contratacion)
VALUES ('Ejemplo 2', 'Test', 'test2@tienda.com', 'Test', 20000, '20250915');
 
-- Como número entero
INSERT INTO empleados (nombre, apellidos, email, puesto, salario, fecha_contratacion)
VALUES ('Ejemplo 3', 'Test', 'test3@tienda.com', 'Test', 20000, 20250915);

Todos estos formatos se almacenan internamente como 2025-09-15. Sin embargo, la recomendación es usar siempre YYYY-MM-DD con guiones para máxima claridad.

Funciones de fecha en INSERT

Puedes usar funciones de MySQL para insertar fechas calculadas:

-- Fecha actual
INSERT INTO empleados (nombre, apellidos, email, puesto, salario, fecha_contratacion)
VALUES ('Nuevo', 'Empleado', 'nuevo@tienda.com', 'Vendedor', 30000, CURDATE());
 
-- Fecha de hace 30 días
INSERT INTO empleados (nombre, apellidos, email, puesto, salario, fecha_contratacion)
VALUES ('Otro', 'Empleado', 'otro@tienda.com', 'Vendedor', 30000, CURDATE() - INTERVAL 30 DAY);

CURDATE() devuelve la fecha actual del servidor. CURDATE() - INTERVAL 30 DAY resta 30 días a la fecha actual. Puedes usar INTERVAL con DAY, MONTH, YEAR y otras unidades.

STR_TO_DATE: convertir cadenas a fecha

Cuando los datos de entrada no están en formato estándar (por ejemplo, al importar de un archivo o de una aplicación que usa un formato diferente), puedes usar STR_TO_DATE() para convertirlos:

-- Formato español: día/mes/año
INSERT INTO pedidos (cliente_id, empleado_id, fecha_pedido, estado, total)
VALUES (1, 4, STR_TO_DATE('15/09/2025', '%d/%m/%Y'), 'pendiente', 100.00);
 
-- Formato con nombre del mes en inglés
INSERT INTO pedidos (cliente_id, empleado_id, fecha_pedido, estado, total)
VALUES (2, 5, STR_TO_DATE('September 15, 2025', '%M %d, %Y'), 'pendiente', 200.00);

Los especificadores de formato más comunes son:

%Y  Año con 4 dígitos (2025)
%y  Año con 2 dígitos (25)
%m  Mes con 2 dígitos (01-12)
%d  Día con 2 dígitos (01-31)
%M  Nombre del mes en inglés (January, February...)
%D  Día con sufijo ordinal en inglés (1st, 2nd, 3rd...)

Fechas con ceros

MySQL permite fechas con componentes a cero como '2025-00-00' o '0000-00-00', pero esta práctica está desaconsejada. El modo SQL NO_ZERO_DATE (activado por defecto en MySQL 8.0) rechaza estas fechas:

-- Esto generará un error o advertencia en MySQL 8.0
INSERT INTO pedidos (cliente_id, empleado_id, fecha_pedido, estado, total)
VALUES (1, 4, '0000-00-00', 'pendiente', 0);

Si necesitas representar "sin fecha", usa NULL en lugar de una fecha con ceros.

Fechas fuera de rango

El tipo DATE acepta valores entre 1000-01-01 y 9999-12-31. MySQL rechaza fechas fuera de este rango y fechas inválidas como el 30 de febrero:

-- Error: el 30 de febrero no existe
INSERT INTO pedidos (cliente_id, empleado_id, fecha_pedido, estado, total)
VALUES (1, 4, '2025-02-30', 'pendiente', 0);
ERROR 1292 (22007): Incorrect date value: '2025-02-30'

MySQL también valida los años bisiestos: 2024-02-29 es válido (2024 fue bisiesto) pero 2025-02-29 no lo es.

Valores DEFAULT con fechas

Al definir una tabla, puedes establecer valores por defecto para columnas de fecha:

CREATE TABLE eventos (
    id INT AUTO_INCREMENT PRIMARY KEY,
    nombre VARCHAR(100) NOT NULL,
    fecha_creacion DATE DEFAULT (CURDATE()),
    fecha_evento DATE NOT NULL
);

DEFAULT (CURDATE()) asigna automáticamente la fecha actual cuando no se proporciona un valor. Las expresiones como DEFAULT requieren paréntesis en MySQL 8.0.13+.

Nuestra tabla clientes usa TIMESTAMP DEFAULT CURRENT_TIMESTAMP para el campo fecha_registro, que funciona de forma similar pero incluye la hora.

Consejo práctico

Si trabajas con una aplicación que recibe fechas del usuario, siempre convierte la fecha al formato YYYY-MM-DD en tu aplicación antes de enviarla a MySQL. No confíes en que MySQL interprete correctamente formatos ambiguos como 01/02/2025 (¿1 de febrero o 2 de enero?). Usa STR_TO_DATE() como último recurso cuando no puedes controlar el formato de entrada.

En el siguiente artículo veremos cómo insertar valores de fecha y hora (DATETIME y TIMESTAMP), que añaden la componente horaria a las fechas.

Escrito por Eduardo Lázaro