Melhor maneira de lidar com datas anteriores a 1000 AD no MySQL?

9

Estou criando um banco de dados para registros que se estendem antes de 1000 AD, mas os campos MySQL Date e DateTime suportam apenas datas iniciando em 1000.

Existe uma maneira mais conveniente do que usar um tipo bigint para contar segundos antes / depois de 1/1/1970 usando um carimbo de data / hora Unix ou mudar para um software de banco de dados que suporte períodos maiores?

David LeBauer
fonte
11
Essa pergunta é respondida muito bem lá no SO: stackoverflow.com/q/2487543/514119
stanleykylee
@stanleykylee obrigado por apontar isso. A pergunta era diferente, mas o problema surgiu em comentários e foi respondido posteriormente, como 'escolha uma data de referência e use um campo numérico', com a ressalva 'seria tedioso para codificar, mas bastante direto' e minha pergunta pergunta, entre outras coisas, se essa é a melhor alternativa.
David LeBauer
Ah, de alguma forma eu perdi isso na pergunta. Permita-me facepalm e remover esses comentários ...
jcolebrand

Respostas:

7

Uma alternativa é armazenar cada parte da data em um campo numérico. Então você teria três campos:

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

Dessa forma, ainda seria legível por humanos. O intervalo de valores para diferentes tipos de dados numéricos no MySQL está disponível em Visão Geral dos Tipos Numéricos . Os requisitos de armazenamento estão disponíveis em Requisitos de armazenamento do tipo de dados .

dabest1
fonte
11
Eu gostaria de dar um +1, mas tenho certeza de que a lógica da data seria horrível, certo?
Camilo Martin
Que tal ter um único campo onde armazenamos datas em formato numérico para, por exemplo 2015/10/12 10:12:05
atpatil11
8

Nenhum tipo de dados de data RDBMS nativo será útil para aplicativos que exigem datas muito antigas (e para algumas, até futuras).

Se eu fosse você, usaria um tipo de seqüência de caracteres para o armazenamento nativo e ficaria com um formato de local significativo como: + AAAA-MM-DD para acomodar o BC / AD e qualquer data histórica ou razoável futura prevista.

Se isso ajudar, você poderá criar uma classe de biblioteca que converta seu formato de armazenamento interno em um formato mais apresentável para a camada da interface do usuário. Você pode até incluir funções de biblioteca que se convertam em um tipo de data nativo, se o idioma de sua escolha suportar as datas que você terá no seu banco de dados.

Joel Brown
fonte
11
Se você estiver usando o SQL Server 2008+, DATETIME2 é a resposta . Período: de 1 de janeiro de 1 dC a 31 de dezembro de 9999 dC.
21411 Nick Chammas
11
Boa sugestão. Para outros sistemas, eu recomendaria adicionalmente uma CHECKrestrição para impor um formato de sequência de datas. Infelizmente, o MySQL não impõe CHECK restrições.
21411 Nick Chammas
2
@ Nick, concordou com o DATETIME2 no SQL Server 2008+, (vou sentir saudades de 1753), mas o OP está começando com o MySQL como sua aposta no terreno. Além disso, mesmo DATETIME2 cai para baixo assim que você precisa adicionar 31 de dezembro de 1 aC ao seu calendário :)
Joel Brown
11
Você sempre pode adicionar uma coluna BITou BOOLEANpara indicar a polaridade da data. :) Obviamente, se você fizer isso, estará por conta própria se realizar cálculos nessas datas "BC". Quem sabe que tipo de ajustes de calendário que são normalmente tomadas de cuidados para nós por funções de biblioteca seriam perdidas enquanto manipulando os "falsos" datas BC ...
Nick Chammas
11
Marque, a razão pela qual eu recomendaria uma string é que, desde que você a formule corretamente, ela será legível por humanos (e até certo ponto editável) sem nenhum processamento e você poderá criar funções especiais de manipulação de datas com relativa facilidade. Armazenar datas como números é terrivelmente inconveniente, a menos que você tenha uma biblioteca de funções que possam interpretar esse tipo de codificação para meros seres humanos. Obviamente, quando essa biblioteca existe, a codificação de uma data como um número é muito mais sensata.
Joel Brown
1

Que tal ter um único campo flutuante na tabela em que armazenamos datas em formato numérico, por exemplo, 2015-10-12 10:12:05 será armazenado em 20151012. 101205. É sempre melhor classificar em campo único em vez de ter 3 ou mais campos diferentes.

A lógica acima não funciona para poucos cenários. Assim, convertemos a data em segundos considerando 1 dia = 86400 segundos. Negativo usado para datas de BC. Funciona como esperado.

atpatil11
fonte
11
números negativos para BC?
22617 Robertgwick #
11
151012 e 150819 ambos seriam em 15AD, -151109 seria em 15BC
Rob Sedgwick