Como eu poderia armazenar uma data que pode ser parcial (ou seja, apenas um ano, talvez o mês também) e output-lo mais tarde com a mesma especificidade?
-
01-07-2019 - |
Pergunta
Eu quero que os usuários especificar uma data que pode ou não incluir um dia e mês O problema é quando ele é armazenado como uma data e hora na DB (mas terá pelo menos o ano.); os desaparecidos dia / mês será guardado como valores padrão e eu vou perder o formato original e significado da data.
A minha ideia era para armazenar o formato real em uma coluna como uma string, além da coluna de data e hora. Então eu poderia usar a coluna corda sempre que tenho para exibir a data ea data e hora para tudo o resto. A desvantagem é uma coluna extra para cada coluna de data na tabela Eu quero exibir e imprimir datas localizadas não será tão fácil, já que eu não posso contar com o valor de data e hora ... Eu provavelmente vou ter que analisar a cadeia .
Eu estou esperando que eu tenha esquecido alguma coisa e pode haver uma maneira mais fácil.
(Nota estou usando Rails se é importante para uma solução.)
Solução
Tal como proposto pelo Jhenzie , criar uma máscara de bits para mostrar quais partes da data foram especificadas. 1 = Ano, 2 = Mês, 4 = Dia, 8 = Hora (se você decidir ser mais específico) e, em seguida, armazenar isso em outro campo.
A única maneira que eu poderia pensar em fazê-lo sem exigindo colunas extras em sua mesa seria usar o método de jhenzie de usar uma máscara de bits, e depois armazenar aquela máscara de bits para o segundo parte do seu datetime coluna.
Outras dicas
no seu modelo só prestar atenção às partes que lhe interessam. Assim, você pode armazenar a data inteira em seu db, mas você se aglutinam-lo antes de exibi-lo para o usuário.
A coluna adicional poderia simples ser utilizado para especificar qual parte do tempo de data foi especificada
1 = dia 2 = mês 4 = ano
modo 3 é dia e mês, 6 meses e ano, 7 é todos os três. é um int simples nesse ponto
Se você armazenar uma string, não parcialmente reinventar ISO 8601 padrão que cobre o caso de você descrever e mais:
É realmente necessário para armazená-lo como uma data e hora em tudo? Se não for armazenado como uma seqüência 2008 ou 2008-8 ou 2008/08/01 - dividir a string em hífens quando você retirá-lo e você é capaz de estabelecer como específica a entrada original era
Eu provavelmente armazenar a data e hora e uma coluna adicional "de precisão" para determinar como para a saída dela. Para a saída, a coluna de precisão pode mapear a uma coluna que contém a correspondente cadeia de formatação ( "AAAA-mm", etc) ou pode conter a própria cadeia de formatação.
Eu não sei muito sobre design de DB, mas acho que uma forma limpa de fazer isso seria com colunas booleano que indica se o usuário tiver mês de entrada e os dias (uma coluna para cada). Então, para salvar a data dada, você:
- Guarde a data em que a entrada do usuário em uma coluna datetime;
- Defina a coluna mês booleano se o usuário tiver escolhido um mês;
- Definir a coluna dia booleano se o usuário tiver escolhido um dia.
Desta forma você sabe quais partes da data e hora que você pode confiar (ou seja, o que era a entrada pelo usuário).
Editar: ele também seria muito mais fácil de entender do que ter um campo int
com valores enigmáticas
O banco de dados Informix tem essa facilidade. Quando você define um campo de data, você também especifica uma máscara de hora e data atributos desejados. Somente esses campos contar ao fazer comparações.
Com diferentes níveis de especificidade, a sua melhor aposta é a de armazená-los como ints anuláveis ??simples. Ano mês dia. Você pode encapsular a lógica de exibição em seu modelo de apresentação ou um objeto de valor em seu domínio.
Built-in tipos representar um instante no tempo. Você pode usar o construída em tipos e criar uma coluna de precisão (ano, mês, dia, hora, etc.) ou você pode criar seus próprios valores nulos estrutura data e usar (ou outro valor inválido) para porções vazias.
Para rubi, pelo menos - você poderia usar esta jóia - parcial-date https://github.com/58bits/partial-date