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 (lo que requiere que la columna no tenga la restricción NOT NULL).

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