El síntoma: un texto con apariencia de fecha no puede convertirse
El patrón suele aparecer al importar CSV, limpiar datos heredados o convertir una columna de texto antes de comparar fechas. Esta expresión representa el problema en motores con un tipo fecha estricto:
CAST('2026-13-01' AS DATE)El formato externo parece YYYY-MM-DD, pero el mes 13 no pertenece al calendario. PostgreSQL y SQL Server rechazan valores que no pueden interpretar como fechas válidas. En MySQL el resultado puede depender del modo SQL. SQLite no es directamente comparable: almacena fechas normalmente como texto, número juliano o Unix timestamp y sus funciones temporales interpretan esos valores.
Tres problemas distintos que conviene diagnosticar por separado
| Problema | Ejemplo | Qué revisar |
|---|---|---|
| Calendario imposible | 2026-13-01 | Rango de mes, día y año |
| Formato ambiguo | 03/04/2026 | Orden día/mes y configuración regional |
| Texto no temporal | pendiente | Origen, limpieza y mapeo de columnas |
No los corrijas del mismo modo. Cambiar separadores no arregla un mes 13; y aceptar una cadena ambigua sin conocer el formato puede producir una fecha válida pero equivocada.
Modelo mental: primero decide qué formato promete la fuente; después valida que las partes formen una fecha real; por último convierte al tipo o representación temporal del motor.
Primera defensa: normaliza el contrato de entrada
Para intercambiar fechas sin hora, YYYY-MM-DD es una representación clara y evita gran parte de la ambigüedad día/mes. Aun así, el patrón visual no basta: 2026-13-01 sigue siendo inválido.
Si controlas la importación, evita mezclar formatos como 31/12/2026, 12-31-2026 y 2026-12-31 en la misma columna. Conserva el texto original en una zona de staging cuando necesites auditar qué filas no se pudieron convertir.
Diagnóstico reproducible en la base educativa con SQLite
SQLite no ofrece un tipo DATE separado. Para la práctica del sitio podemos usar date() como comprobación de valores que la función no reconoce. Con un mes imposible, devuelve NULL:
WITH importados(id, fecha_texto) AS (
VALUES
(1, '2026-09-15'),
(2, '2026-13-01'),
(3, '2026-10-03')
)
SELECT id, fecha_texto
FROM importados
WHERE date(fecha_texto) IS NULL;| id | fecha_texto |
|---|---|
| 2 | 2026-13-01 |
Esta comprobación sirve para detectar entradas claramente no interpretables en SQLite, pero no debe convertirse en una promesa de validación universal. Algunas fechas fuera del calendario pueden normalizarse en ciertas funciones o versiones; para una importación crítica, valida también las reglas de negocio y el formato acordado.
Cómo cambia la conversión entre motores
PostgreSQL
Los tipos de fecha/hora interpretan la cadena según sus reglas de entrada y la configuración DateStyle cuando el orden es ambiguo. Si un campo de mes o día queda fuera de rango, el parser rechaza el valor. Para datos de intercambio, usa una forma no ambigua y evita depender de la configuración de la sesión.
MySQL 8.4
El comportamiento de fechas inválidas depende del modo SQL. En modo estricto, valores de fecha inválidos pueden producir un error; con configuraciones más permisivas pueden convertirse a valores cero o generar advertencias. Por eso una carga que «funciona» en una instalación no garantiza el mismo resultado en otra.
SQL Server
Las conversiones a date rechazan valores que no reconoce como fechas válidas. Si estás limpiando una columna de texto y quieres localizar fallos sin abortar toda la consulta, TRY_CONVERT devuelve NULL cuando la conversión permitida no tiene éxito:
SELECT TRY_CONVERT(date, fecha_texto, 23) AS fecha
FROM importados;El estilo 23 corresponde a la forma yyyy-mm-dd. Después puedes revisar las filas cuyo resultado sea NULL antes de insertarlas en la tabla definitiva.
SQLite
SQLite no tiene un tipo fecha/hora dedicado. Sus funciones aceptan representaciones temporales concretas y devuelven texto o números según la función. No uses CAST(... AS DATE) como si fuera equivalente a PostgreSQL o SQL Server: para esta intención, trabaja con date(), datetime() o una representación ISO-8601 coherente.
Método de diagnóstico en seis pasos
- Ejecuta o inspecciona el valor de texto original sin convertirlo.
- Confirma el formato prometido por la fuente: por ejemplo,
YYYY-MM-DD. - Separa formato inválido de fecha imposible: no son el mismo problema.
- Comprueba la configuración del motor cuando pueda alterar la interpretación o severidad.
- Localiza las filas inválidas en staging antes de modificar la tabla final.
- Corrige el dato o la regla de importación; no reemplaces silenciosamente una fecha desconocida por otra inventada.
Práctica correctiva
Separa las filas que necesitan revisión
Recibes cuatro valores de fecha como texto. En SQLite, identifica los que date() no reconoce.
Criterio de éxito: la consulta devuelve los identificadores 2 y 4, sin modificar los textos originales.
VALUES.date(fecha_texto) a cada fila.NULL.Solución razonada
WITH importados(id, fecha_texto) AS (
VALUES
(1, '2026-11-05'),
(2, '2026-00-20'),
(3, '2026-12-01'),
(4, 'texto')
)
SELECT id, fecha_texto
FROM importados
WHERE date(fecha_texto) IS NULL
ORDER BY id;2026-00-20 usa un mes inválido y texto no tiene una forma temporal reconocible. Las otras dos filas permanecen fuera del diagnóstico porque date() sí las interpreta.
Qué debes recordar
- Una cadena con forma de fecha puede seguir siendo inválida por sus valores de calendario.
- Los formatos ambiguos dependen de reglas de sesión o motor; evita apoyarte en ellas para intercambiar datos.
- MySQL puede cambiar su reacción según el modo SQL; PostgreSQL y SQL Server son más estrictos con valores no válidos.
- SQLite no tiene un tipo
DATEdedicado; usa sus funciones temporales y una representación coherente. - En una importación, conserva el valor original y separa las filas inválidas antes de cargar datos definitivos.
Conceptos relacionados
Fuentes técnicas
Las diferencias de interpretación y conversión se contrastaron con documentación primaria: