Eu quero ser capaz de capturar fatos como Bob was born in 2000
e Bill's birthday is May 7th
.
Nos dois exemplos, conhecemos apenas parte da data de nascimento da pessoa. Em um caso, sabemos apenas o ano; no outro caso, sabemos o mês e o dia, mas não o ano.
Como capturo essas informações?
Alguns exemplos de como isso pode funcionar:
Imagine uma biblioteca como datetime que permita que None nos campos represente incógnitas. Eu posso ter um código como o seguinte:
date_a = date(2000, 5, None)
date_b = date(2000, 6, None)
difference = date_b - date_a
assert difference.min.days == 1
assert difference.max.days == 60 # Or something close to 60.
assert equal(date_a, date_b) == False
date_c = date(2000, 5, None)
assert equal(date_a, date_c) == Maybe
Este é apenas um exemplo de como ele pode se comportar. Eu não necessariamente quero esse comportamento preciso.
Respostas:
Primeiro de tudo, quando você começa a decompor as datas em seus componentes constituintes, elas não são mais datas.
Da mesma forma que não é possível remover a funcionalidade via subclasses sem interromper o OOP, não é possível misturar datas e frações de datas sem causar confusão (ou pior), tornando-as compatíveis como no seu exemplo de código sem interromper outra coisa.
Se você deseja capturar um ano, o que há de errado com um objeto que contém um número inteiro simples? Se você deseja capturar um mês e um dia, por que não capturar uma enumeração de mês e um dia inteiro? Talvez até armazene-os internamente em um objeto de data para obter uma verificação adequada dos limites (por exemplo, 31 de fevereiro não faz sentido). Expor uma interface diferente, no entanto.
Por que você deseja comparar uma data com um ano para ver se são iguais, maiores ou menores? Não faz sentido: não há informações suficientes para fazer essa comparação. No entanto, existem outras comparações que podem fazer sentido (este é o pseudocódigo):
fonte
O segundo comentário de Robert Harvey contém a resposta certa, mas deixe-me expandir um pouco.
O ano de nascimento e as datas de nascimento das pessoas são entidades completamente diferentes, portanto você não precisa (e realmente não deve) usar o mesmo mecanismo para ambos.
Para datas de nascimento, você pode criar um
BirthDate
tipo de dados (ou possivelmente um nomeYearlyRecurringDate
que eu não consiga inventar agora) que conteria apenasdate
um ano constante, como 2000 por convenção. O ano de 2000 é uma boa escolha, porque foi um salto; portanto, não falhará as pessoas cujo aniversário é em 28 de fevereiro.Durante anos de nascimento, você pode inventar um
BirthYear
tipo de dados (ou possivelmente umApproximateDate
tipo de dados) que conterá umadate
, e um indicador da precisão:Year
,Month
,Full
.O benefício dessas abordagens é que, no centro das coisas, você ainda mantém um
date
para poder executar a aritmética de datas.fonte
Acredito que o que você está descrevendo seria um substituto para o
datetime
módulo que implementa osdatetime.datetime
atributos (ano, mês etc.) como valores com uma medição de incerteza (em vez de apenas valores).Existem pacotes Python para ajudar com números incertos (por exemplo, o pacote de incertezas ), e talvez não seja muito difícil criar uma bifurcação
datetime
que use incerteza em cada atributo. Eu também gostaria de ver um e pode até ter utilidade para ele. Certamente, poderia ser argumentado para a inclusão de umudatetime
no pacote de incertezas vinculado anteriormente.Seus exemplos seriam algo como:
"Valores de sinal" têm muitos problemas, mas além disso, você pode representar coisas com incerteza que os valores de sinal não podem:
Outra consideração é que, para ser mais preciso, as incertezas aqui devem realmente ser do tipo
timedelta
. Deixo como exercício para o leitor descobrir um construtor conciso e completo para oudatetime
uso detimedelta
incertezas.Então, em última análise, eu diria que o que você descreve é "facilmente" modelado com incertezas, mas a implementação de a
udatetime
é praticamente bastante difícil. A maioria seguirá a rota "fácil" e dividirá a data e hora em componentes e rastreará a incerteza sobre eles de forma independente, mas se você estiver se sentindo ambicioso, ouncertainties
pacote (ou outro) pode estar interessado em uma solicitação de recebimentoudatetime
.fonte
Por que não criar uma classe "período" que implemente um de para a estrutura.
"Bob nasceu em 2000" ->
Você pode implementar vários métodos de pesquisa, colocando entre as datas de e até. O atributo fuzz fornece uma indicação útil da precisão da data, para que você possa especificar fuzz == 1 para correspondências exatas ou fuzz == 31 para dentro de um mês ou mais.
fonte