¿La mejor manera de manejar fechas anteriores a 1000 AD en MySQL?


9

Estoy creando una base de datos para registros que se extienden antes de 1000 AD, pero los campos MySQL Date y DateTime solo admiten fechas que comienzan en 1000.

¿Hay alguna manera que sería más conveniente que usar un tipo bigint para contar segundos antes / después del 1/1/1970 usando una marca de tiempo Unix, o cambiar a un software de base de datos que admita rangos de fechas más grandes?


1
Esto se responde bastante bien en SO: stackoverflow.com/q/2487543/514119
stanleykylee

@stanleykylee gracias por señalar eso. La pregunta era diferente, pero el problema surgió en los comentarios y posteriormente se respondió a lo largo de las líneas de 'elegir una fecha de referencia y usar un campo numérico', con la advertencia 'sería tedioso codificar, pero bastante sencillo' y mi pregunta pregunta, entre otras cosas, si esta es la mejor alternativa.
David LeBauer

Ah, de alguna manera extrañé eso en la pregunta. Me permitirá a facepalm y eliminar estos comentarios ...
jcolebrand

Respuestas:


7

Una alternativa es almacenar cada parte de la fecha en un campo numérico. Entonces tendrías tres campos:

year  SMALLINT     # Store positive values for AD and negative for BC years.
month TINYINT
day   TINYINT

De esta manera, aún sería legible para los humanos. El rango de valores para diferentes tipos de datos numéricos en MySQL está disponible en Descripción general de tipos numéricos . Los requisitos de almacenamiento están disponibles en Requisitos de almacenamiento de tipo de datos .


1
Me gustaría darle a esto un +1, pero estoy bastante seguro de que la lógica de la fecha sería horrible, ¿verdad?
Camilo Martin

¿Qué tal tener un solo campo donde almacenamos fechas en formato numérico para, por ejemplo, 2015-10-12 10:12:05
atpatil11

8

Ningún tipo de datos de fecha RDBMS nativo servirá para aplicaciones que requieren fechas muy antiguas (y para algunas, incluso futuras).

Si yo fuera usted, usaría un tipo de cadena para el almacenamiento nativo y me quedaría con un formato de lugar significativo como: + AAAA-MM-DD para acomodar BC / AD y cualquier fecha histórica histórica o razonable previsible.

Si puede ayudar, puede crear una clase de biblioteca que convierta su formato de almacenamiento interno en uno más presentable para la capa de interfaz de usuario. Incluso puede incluir funciones de biblioteca que se conviertan a un tipo de fecha nativo, si su idioma de elección admite las fechas que tendrá en su base de datos.


1
Si está utilizando SQL Server 2008+, DATETIME2 es la respuesta . Rango de fechas: 1 de enero de 1 DC hasta el 31 de diciembre de 9999 DC.
Nick Chammas

1
Buena sugerencia. Para otros sistemas, también recomendaría una CHECKrestricción para aplicar un formato de cadena de fecha. Por desgracia, MySQL no impone CHECK restricciones.
Nick Chammas

2
@Nick, acordó sobre DATETIME2 en SQL Server 2008+, (voy a extrañar 1753) pero OP está comenzando con MySQL como su apuesta en el terreno. Además, incluso DATETIME2 se cae tan pronto como necesite agregar 31 de diciembre, 1 AC a su calendario :)
Joel Brown

1
Siempre puede agregar una columna BITo BOOLEANpara indicar la polaridad de la fecha. :) Por supuesto, si haces eso, estás solo si haces cálculos en esas fechas "BC". Quién sabe qué tipo de ajustes de calendario que normalmente se ocupan de las funciones de la biblioteca se perderían al manipular las fechas "falsas" de BC ...
Nick Chammas

1
Mark, la razón por la que recomendaría una cadena es que, siempre y cuando la formules correctamente, será legible por humanos (e incluso hasta cierto punto editable) sin ningún procesamiento y puedes construir funciones especiales de manipulación de fechas con relativa facilidad. Almacenar las fechas como números es terriblemente inconveniente, a menos que tenga una biblioteca de funciones que pueda interpretar ese tipo de codificación para simples humanos. Por supuesto, cuando dicha biblioteca está en su lugar, codificar una fecha como un número es mucho más sensato.
Joel Brown el

1

¿Qué tal si tenemos un único campo flotante en la tabla donde almacenamos fechas en formato numérico para, por ejemplo, 2015-10-12 10:12:05 se almacenará 20151012. 101205. Siempre es mejor ordenar en un solo campo en lugar de tener 3 o más Diferentes campos.

La lógica anterior no funciona para algunos escenarios. Por lo tanto, hemos convertido la fecha en segundos considerando 1 día = 86400 segundos. Usado negativo para las fechas de BC. Funciona como se esperaba.


1
números negativos para BC?
Rob Sedgwick

1
151012 y 150819 estarían en 15AD, -151109 en 15BC
Rob Sedgwick
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.