2011-07-30 31 views
20

Deseo ofrecer al usuario la posibilidad de introducir fechas incompletas (por ejemplo, solo el año 2005 o enero de 1998) pero también fechas completas con año, mes y día. ¿Puedo lograr esto usando un solo campo de fecha en el DB?Almacenar fecha incompleta en el campo de fecha MySQL

He intentado UPDATE tableA SET mydate = '2001-00-00' y parece que funciona (no hay errores), pero no estoy seguro de si esto es correcto. Internamente, supongo que se usa una marca de tiempo, entonces, ¿cómo puede MySQL representar esos 0?

+0

¿Qué obtienes cuando consultas 'SELECT mydate FROM tableA'? – phlogratos

+0

El valor correcto, es decir, 2001-00-00. Mi preocupación es solo que estoy explotando un comportamiento no estándar que se basa en algún truco que algún día podría romperse o no funcionar en ciertas circunstancias. –

Respuesta

22

Hay una pequeña nota en el documentation for the DATE_FORMAT() sobre MySQL permitiendo fechas incompletas:

rangos para los especificadores de mes y día comienzan con cero debido al hecho de que MySQL permite el almacenamiento de fechas incompletas como ' 2014-00-00 '.

Como ha señalado @wonk0, se establece fechas inválidas a 0000-00-00 00:00:00ALLOW_INVALID_DATES cuando no se establece MySQL. Sin embargo, incluso cuando ALLOW_INVALID_DATES no está configurado, insertar un año válido con mes y día establecido en cero no parece desencadenar este comportamiento, al menos no en mis pruebas (MySQL 5.1.54-1ubuntu4). He utilizado esta característica antes sin ningún problema, pero hasta ahora no he podido encontrar ninguna documentación más detallada que describa este comportamiento en su totalidad.

Las comparaciones de fecha y hora también parecen funcionar como se esperaba: por ejemplo, 2011-01-00 > 2011-00-00 y 2011-00-01 > 2011-00-00 hacen lo que cabría esperar.

ACTUALIZACIÓN

Ver this answer (por otro Mike) a una pregunta similar. Apunta a un extracto de La guía definitiva para MySQL 5:

En las versiones anteriores de MySQL, la fecha y tipos de datos DATETIME hicieron solamente una cantidad limitada de la comprobación de tipos. Los valores entre 0 y 12 para meses, y 0 y 31 para días fueron generalmente permitidos. Sin embargo, es la responsabilidad del programa del cliente de proporcionar datos correctos. (Para ejemplo, 0 es un valor permisible para un mes o días, con el fin de proporcionar la posibilidad de almacenar datos incompletos o desconocidos.)

A partir de MySQL 5.0.2, existe una validación más a fondo, por lo que solo se pueden almacenar datos válidos. Todavía están permitidos el mes y valores del día 0, así como la fecha 0000-00-00.

+1

¿Es incorrecta la suposición de que una marca de tiempo se usa para almacenar la fecha? Porque no veo cómo puede representar 2011-00-00 como una marca de tiempo. –

+1

@Omar Kohl: Sí, creo que esa suposición es incorrecta. Un 'TIMESTAMP' tiene un rango menor que' DATETIME'. Un 'DATETIME' usa 8 bytes, mientras que' TIMESTAMP' usa 4 bytes. Consulte [Requisitos de almacenamiento de tipo de datos] (http://dev.mysql.com/doc/refman/5.5/en/storage-requirements.html#id918335) – Mike

+1

Excelente respuesta, la mejor que he encontrado buscando en todas partes. –

2

Bueno, si utilizó un campo de fecha, entonces debería esperar esos 0. Una forma de deshacerse de ellos es utilizar la selección varchar. Sin embargo, es mejor utilizar un campo de fecha, ya que eso es lo que está almacenado allí.

Si tiene que permitir a los usuarios introducir una fecha incompleta, entonces tiene que ser un varchar y en ese caso se puede dar formato a la entrada con su guión y almacenar en esa columna

+0

Ese sería mi último recurso. Por supuesto, tener las cosas en formato de fecha siempre es mejor para ordenar, etc. –

+1

sí, así que en lugar de permitir a los usuarios formatear la fecha, te aconsejo que simplemente permitas que sql formatee el actual 'datetimestamp' allí – DaMainBoss

+0

+1 punto muy bueno. Dats lo que habría hecho –

1

partes almacenamiento de fechas depende de la modo sql MySQL se está ejecutando. Por favor, lea http://dev.mysql.com/doc/refman/5.1/en/server-sql-mode.html, especialmente sobre las fechas no válidas en http://dev.mysql.com/doc/refman/5.1/en/server-sql-mode.html#sqlmode_allow_invalid_dates.

+1

"ALLOW_INVALID_DATES: No realice una verificación completa de las fechas. Verifique que el mes esté en el rango de 1 a 12 y el día esté en el rango de 1 a 31." En este caso, no se aplica porque ni el mes ni el día están en ese rango ... (00 ambos) –

+0

'Compruebe solo que el mes está en el rango de 1 a 12 y el día está en el rango de 1 a 31' ¿Por qué esto permite un mes o un día de 0? – phlogratos

Cuestiones relacionadas