Español


Español


Base de conocimientos

Gestión de datos de tipo "DATE" con MySQL y MariaDB


KB-LJW-DB-104



  




Artículos y recursos relacionados




Las fechas y MySQL: un matrimonio fallido




El momento de la explosión


Dé las gracias a MySQL




Consejos y buenas prácticas


Consejos durante el diseño del schema


Almacenar las fechas en DATETIME


No almacenar fechas en VARCHAR

SQL
-- Leer desde el campo "d_date_txt" de tipo VARCHAR.
-- Intentar convertir la cadena en fecha según el patrón indicado.
----- Fallará en el primer dato que no respete el patrón indicado.
SELECT
   STR_TO_DATE(d_date_txt, '%Y-%m-%d %H:%i:%s') AS d_date_safe
FROM miTabla;


Definir un valor por defecto


NULL
SQL
-- Creación de tabla
-- Utilizar un valor NULL por defecto => Válido en MySQL y MariaDB
CREATE TABLE contactRequests (
  d_dateReceived DATETIME NULL DEFAULT NULL
);


CURRENT_TIMESTAMP
SQL
-- Creación de tabla
CREATE TABLE contactRequests (
   d_dateReceived DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);

-- Modificación de una tabla existente
ALTER TABLE contactRequests MODIFY d_dateReceived DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP;


SQL
-- No especificar el campo "d_dateReceived":
-- se rellena automáticamente con la fecha actual.
INSERT INTO contactRequests (s_firstname, s_lastname)
VALUES ('John', 'Duff');

-- Proporcionar explícitamente CURRENT_TIMESTAMP
-- (redundante e innecesario, pero funcional)
INSERT INTO contactRequests (s_firstname, s_lastname, d_dateReceived)
VALUES ('John', 'Duff', CURRENT_TIMESTAMP);

-- Proporcionar explícitamente NULL
-- => ¡PROVOCA UN ERROR!
INSERT INTO contactRequests (s_firstname, s_lastname, d_dateReceived)
VALUES ('John', 'Duff', NULL);


0000-00-00 00:00:00
SQL
-- Creación de tabla
-- Utilizar una fecha inválida por defecto => históricamente tolerada por MySQL
CREATE TABLE contactRequests (
   d_dateReceived DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00'
);



Hacer obligatoria la fecha

SQL
-- Crear la tabla
---- d_dateReceived es obligatorio
---- NULL está prohibido
---- no se proporciona ningún valor por defecto
---- toda consulta INSERT/UPDATE debe proporcionar explícitamente d_dateReceived; de lo contrario, fallará
CREATE TABLE contactRequests (
  d_dateReceived DATETIME NOT NULL
);

-- Modificar la tabla existente
-- Fallará si una sola fila aún contiene NULL en d_dateReceived => Limpiar la tabla antes.
---- d_dateReceived es obligatorio
---- NULL está prohibido
---- no se proporciona ningún valor por defecto
---- toda consulta INSERT/UPDATE debe proporcionar explícitamente d_dateReceived; de lo contrario, fallará
ALTER TABLE contactRequests
MODIFY d_dateReceived DATETIME NOT NULL;



SQL
-- Ejemplo sin ningún valor proporcionado:
-- La consulta provoca un error.
INSERT INTO contactRequests (s_firstname, s_lastname)

-- Ejemplo con un valor válido:
-- La consulta es aceptada.
INSERT INTO contactRequests (s_firstname, s_lastname, d_dateReceived)
VALUES ('John', 'Duff', '2026-09-01 14:35:12');

-- Ejemplo de consulta con CURRENT_TIMESTAMP:
-- CURRENT_TIMESTAMP se utiliza aquí como valor explícito y no como valor por defecto.
-- La consulta es aceptada.
INSERT INTO contactRequests (s_firstname, s_lastname, d_dateReceived)
VALUES ('John', 'Duff', CURRENT_TIMESTAMP);


SQL
-- Crear la tabla
---- d_dateReceived es obligatorio
---- NULL está prohibido
---- no se proporciona ningún valor por defecto
---- toda consulta INSERT/UPDATE debe proporcionar explícitamente d_dateReceived; de lo contrario, fallará
---- Restricción adicional: Prohíbe las fechas anteriores a 2012
CREATE TABLE contactRequests (
   d_dateReceived DATETIME NOT NULL,
   CONSTRAINT chk_dateReceived
      CHECK (d_dateReceived >= '2012-01-01')
);

-- Modificar la tabla existente
-- Fallará si una sola fila aún contiene NULL en d_dateReceived => Limpiar la tabla antes.
---- d_dateReceived es obligatorio
---- NULL está prohibido
---- no se proporciona ningún valor por defecto
---- toda consulta INSERT/UPDATE debe proporcionar explícitamente d_dateReceived; de lo contrario, fallará
---- Restricción adicional: Prohíbe las fechas anteriores a 2012
ALTER TABLE contactRequests
ADD CONSTRAINT chk_dateReceived
CHECK (d_dateReceived >= '2012-01-01');



Consejos durante la importación de datos


Importar gracias al sql_mode



 Haga clic para ordenar por columna
NivelMétodo de definiciónUbicaciónAlcance realImpactoPersistenciaRecomendaciones
1. Bajo nivel[mysqld]my.iniGlobal del servidorTodas las conexiones
(después del arranque)

(al reiniciar)
Debe priorizarse en producción para imponer reglas coherentes y evitar conexiones permisivas.
2. AdminSET GLOBAL sql_mode = ...SQL ejecutado con privilegios admin
(cmd > mysql)
Global del servidor
(solo para nuevas conexiones)
Solo nuevas sesionesNo
(perdido al reiniciar)
Útil para un cambio inmediato sin editar la configuración [mysqld].
3. SesiónSET SESSION sql_mode = ...SQL ejecutado por aplicación/herramienta
(phpMyAdmin, HeidiSQL, etc.)
Sesión actual
(una conexión)
Una sola conexiónN/A
(vive durante la conexión)
Adecuado para usos puntuales, importaciones, scripts.
4. Aplicativo (alto nivel)INITSTMT=SET SESSION sql_mode=...Cadena DSN / conexión ODBCSesión actual
(en cada apertura de conexión mediante este DSN)
Conexiones que utilizan este DSNN/A
(reaplicado en cada nueva conexión mediante este DSN)
Útil para estandarizar el cliente ODBC.


Limpiar después de la importación


Buscar las fechas inválidas (fechas a Cero)
SQL
-- El campo d_dateReceived es de tipo Date
-- El umbral 1000-01-01 cubre las fechas técnicamente almacenables,
-- pero inválidas según el estándar SQL.
SELECT *
FROM contactRequests
WHERE d_dateReceived = '0000-00-00 00:00:00'
   OR d_dateReceived < '1000-01-01';

  • o bien eliminar las líneas afectadas
  • o bien reemplazarlas por una fecha real de negocio (ej. fecha de creación, fecha de pedido, etc.)
  • o bien reemplazarlas por NULL


Reemplazar las fechas incorrectas por NULL (fechas a Cero)
SQL
UPDATE contactRequests
SET d_dateReceived = NULL
WHERE d_dateReceived = '0000-00-00 00:00:00'
   OR d_dateReceived < '1000-01-01';


Modificar el schema (fechas a Cero)



Consejos al escribir datos


No proporcionar un valor vacío

ASP CLASSIC
<%
'Especificar NULL mediante una consulta SQL clásica
'-	-	-	-	-	-	-	-	-	-	-	-
strSQL = "INSERT INTO contactRequests (d_dateReceived) VALUES (NULL)"
dbConn.Execute(strSQL)


'Especificar NULL mediante una consulta SQL parametrizada
'-	-	-	-	-	-	-	-	-	-	-	-
'No utilice vbNull: es una constante de tipo (máscara interna de VBScript)
Set paramCmd = Server.CreateObject("ADODB.Command")
Set paramCmd.ActiveConnection = dbConn
paramCmd.CommandText = "INSERT INTO contactRequests (d_dateReceived) VALUES (?)"
paramCmd.Parameters.Append paramCmd.CreateParameter("@d_dateReceived", adDBTimeStamp, adParamInput, , Null)
paramCmd.Execute
%>


Proporcionar una fecha en formato ISO

ASP CLASSIC
<%
'Devolver una fecha formateada para MySQL/MariaDB en el formato "YYYY-MM-DD HH:MM:SS"
Function DateFormat_MySQL_MariaDB(byVal dtInput)

   'Parámetro  Variable   Tipo          Descripción
   '---------  --------   ----          -----------
   '@param     dtInput    String/Date   Fecha o Fecha/Hora (tipo VBScript/ASP "String" o "Date")
   '@return    dtOutput   String/Null   Cadena de fecha formateada "YYYY-MM-DD HH:MM:SS", o bien Null.

   Dim sYear, sMonth, sDay, sHour, sMinute, sSecond
   Dim dtOutput : dtOutput = Null
   
   'Si la entrada es convertible al tipo "Date"
   If (IsDate(dtInput)) Then
      'Recuperar las partes de la fecha
      sYear   = CStr(Year(dtInput))
      sMonth  = Right("0" & Month(dtInput), 2)
      sDay    = Right("0" & Day(dtInput), 2)
      
      'Verificar si hay una hora presente
      If ((Hour(dtInput) + Minute(dtInput) + Second(dtInput)) > 0) Then
         sHour   = Right("0" & Hour(dtInput), 2)
         sMinute = Right("0" & Minute(dtInput), 2)
         sSecond = Right("0" & Second(dtInput), 2)
      Else
         sHour   = "00"
         sMinute = "00"
         sSecond = "00"
      End If
      
      'Construir la cadena de fecha en formato ISO para MySQL/MariaDB
      dtOutput = sYear & "-" & sMonth & "-" & sDay & " " & sHour & ":" & sMinute & ":" & sSecond
   Else
      dtOutput = Null 'Devolver Null si la entrada no es una fecha válida
   End If

   'Return
   DateFormat_MySQL_MariaDB = dtOutput

End Function 'DateFormat_MySQL_MariaDB



'= =  =  =  =  =  =
'Ejemplos de uso
'= =  =  =  =  =  =

Dim dateSource, datetimeSource, dateStringForSQL

'Ej. Gestión de una fecha en Inglés
'----------------------------------
SetLocale(1033) 'Configurar el LCID en Inglés

'Definir/leer una fecha de origen (en formato Inglés) – de tipo vbString.
dateSource = "04/13/2026" 'ej. 13 Abril

'Devolver la fecha formateada para MySQL/MariaDB
'=> DEVUELVE: 2026-04-13 00:00:00
dateStringForSQL = DateFormat_MySQL_MariaDB(dateSource)


'Ej. Gestión de una fecha en Francés
'-----------------------------------
SetLocale(1036) 'Configurar el LCID en Francés

'Definir/leer una fecha y hora de origen (en formato Francés) – de tipo vbDate.
datetimeSource = #01/09/2026 14:35:12# 'ej. 1 septiembre

'Devolver la fecha formateada para MySQL/MariaDB
'=> DEVUELVE: 2026-09-01 14:35:12
dateStringForSQL = DateFormat_MySQL_MariaDB(datetimeSource)


'Definir la consulta de inserción en la base de datos
'Utilizar la fecha ya correctamente formateada para MySQL/MariaDB
strSQL = _
   "INSERT INTO contactRequests ( " & _
      "s_firstname, " & _
      "s_lastname, " & _
      "d_dateReceived " & _
   ") VALUES ( " & _
      "'John', " & _
      "'Duff', " & _
      "STR_TO_DATE('" & dateStringForSQL & "') " & _
   ") "

'Agregar en la base de datos
dbConn.Execute(strSQL)
%>


Proporcionar una fecha en formato personalizado

ASP CLASSIC
<%
'Definir un datetime con un formato arbitrario/exótico – de tipo vbString.
Dim datetimeSource : datetimeSource = "Ano=2026 Mes=09 Hora=14 Segundo=12 Dia=01 Minuto=35"

'Definir una máscara/patrón que permita a MySQL/MariaDB entender la cadena proporcionada
'(contiene los marcadores %Y %m %d %H %i %s, reconocidos por MySQL/MariaDB)
Dim datetimeMask : datetimeMask = "Ano=%Y Mes=%m Hora=%H Segundo=%s Dia=%d Minuto=%i"

'Definir la consulta de inserción en la base de datos
strSQL = _
   "INSERT INTO contactRequests (" & _
      "s_firstname, " & _
      "s_lastname, " & _
      "d_dateReceived " & _
   ") VALUES (" & _
      "'John', " & _
      "'Duff', " & _
      "STR_TO_DATE('" & datetimeSource & "', '" & datetimeMask & "') " & _
   ")"

'Agregar en la base de datos
dbConn.Execute(strSQL)
%>




Dejar que el motor SQL utilice la fecha actual




Consejos al leer datos


Utilizar consultas parametrizadas


Gestionar los valores sucios

SQL
-- VARIANTE 1: Más concisa
-- El rendimiento es equivalente entre CASE y NULLIF incluso en grandes cantidades de datos.
-- CAST() no tiene impacto en términos de rendimiento.
-- *  *  *  *  *
-- Leer desde el campo "d_date" de tipo DATETIME
-- Asegurarse de que el dato sea una fecha válida
-- Devuelve NULL en caso contrario
SELECT
   CAST(
      NULLIF(
         IF(d_date < '1000-01-01', NULL, d_date),
         '0000-00-00 00:00:00'
      )
   AS DATETIME) AS d_date_safe
FROM contactRequests

-- VARIANTE 2: Más legible
-- El rendimiento es equivalente entre CASE y NULLIF incluso en grandes cantidades de datos.
-- CAST() no tiene impacto en términos de rendimiento.
-- *  *  *  *  *
-- Leer desde el campo "d_date" de tipo DATETIME
-- Asegurarse de que el dato sea una fecha válida
-- Devuelve NULL en caso contrario
SELECT
   CAST(
      CASE
         WHEN d_date = '0000-00-00 00:00:00' THEN NULL
         WHEN d_date < '1000-01-01'          THEN NULL
         ELSE d_date
      END
   AS DATETIME) AS d_date_safe
FROM contactRequests


SQL
-- Leer desde el campo "d_date_txt" de tipo VARCHAR.
-- Intentar convertir la cadena en fecha según el patrón indicado.
----- Fallará en el primer dato que no respete el patrón indicado.
SELECT
   STR_TO_DATE(d_date_txt, '%Y-%m-%d %H:%i:%s') AS d_date_safe
FROM miTabla;


SQL
SELECT d_date FROM miTabla WHERE d_date IS NOT NULL



Leer una fecha en formato personalizado

ASP CLASSIC
<%
'Se desea recuperar la fecha con el siguiente formato exótico: YYYY/MM hh:ss
'   El uso de esta función DATE_FORMAT() ralentiza la consulta.
'   Por lo tanto, será más eficiente leer el dato bruto desde MySQL/MariaDB
'   y luego utilizar ASP/VBScript para extraer las partes y formatearlo.Dim dateMask : dateMask = "%Y/%m %H:%i"

'Definir la consulta de lectura
Dim strSQL : strSQL = "SELECT DATE_FORMAT(contactRequests.d_dateReceived, '" & dateMask & "') AS myDate FROM contactRequests "

'Abrir la conexión
Set dbConn = Server.CreateObject("ADODB.Connection")
dbConn.Open dbConnString

'Abrir el Recordset en modo "Forward-Only" mediante .Execute()
Set rs = dbConn.Execute(strSQL)
%>


Sortear las fechas a Cero







Al servicio de su ASP Classic





Preferentias de privacidadPreferencias relacionadas con sus datos personales.

NOTA : Sus cambios se aplicarán desde la página siguiente que visitará/cargará.

Su privacidad es preciosa: la respetamos.

Al usar este sitio, usted acepta que usemos estadísticas anónimas para analizar nuestro tráfico y mejorar su experiencia de navegación en nuestro sitio, además de tecnologías y cookies para personalizar el contenido. Esta información anónima se puede compartir con nuestros socios de redes sociales y de análisis de confianza.

  • No recolectamos ningún dato nominativo.
  • No almacenamos ninguna contraseña.
  • Utilizamos un algoritmo de seguridad de alto nivel.