Je veux pouvoir saisir des faits comme Bob was born in 2000
et Bill's birthday is May 7th
.
Dans les deux exemples, nous ne connaissons qu'une partie de la date de naissance de la personne. Dans un cas, nous ne connaissons que l'année; dans l'autre cas, nous connaissons le mois et le jour, mais pas l'année.
Comment capturer ces informations?
Quelques exemples de la façon dont cela pourrait fonctionner:
Imaginez une bibliothèque comme datetime qui permettait à None dans les champs de représenter des inconnues. Je pourrais avoir un code comme celui-ci:
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
Ceci est juste un exemple de la façon dont il pourrait se comporter. Je ne veux pas nécessairement ce comportement précis.
Réponses:
Tout d'abord, une fois que vous avez commencé à décomposer les dates en leurs composants, elles ne sont plus des dates.
De la même manière qu'il n'est pas possible de supprimer des fonctionnalités via des sous-classes sans casser la POO, il n'est pas possible de mélanger les dates et les fractions de date sans causer de confusion (ou pire) en les rendant compatibles comme dans votre exemple de code sans casser autre chose.
Si vous voulez capturer une année, quel est le problème avec un objet contenant un simple entier? Si vous voulez capturer un mois et un jour, pourquoi ne pas capturer un dénombrement d'un mois et un jour entier? Peut-être même les stocker en interne dans un objet date afin que vous obteniez une vérification des limites appropriées (par exemple, le 31 février n'a aucun sens). Exposez cependant une interface différente.
Pourquoi voudriez-vous comparer une date à une année pour voir si elles sont identiques, supérieures ou inférieures? Cela n'a aucun sens: il n'y a pas suffisamment d'informations pour faire cette comparaison. Cependant, il existe d'autres comparaisons qui pourraient avoir un sens (c'est un pseudocode):
la source
Le deuxième commentaire de Robert Harvey contient la bonne réponse, mais permettez-moi de développer un peu.
L'année de naissance et la date de naissance des personnes sont des entités complètement différentes, vous n'avez donc pas besoin (et en fait vous ne devriez pas) d'utiliser le même mécanisme pour les deux.
Pour les dates de naissance, vous pouvez concevoir un
BirthDate
type de données (ou peut-êtreYearlyRecurringDate
même si je ne peux pas trouver un nom décent pour l'instant) qui ne contiendrait qu'undate
avec une année constante, comme 2000 par convention. L'an 2000 est un bon choix car il a fait un bond en avant, il ne manquera donc pas aux personnes dont l'anniversaire est le 28 février.Pour les années de naissance, vous pouvez concevoir un
BirthYear
type de données (ou peut - être unApproximateDate
type de données) qui contiendrait undate
, et un indicateur de la précision:Year
,Month
,Full
.L'avantage de ces approches est qu'au cœur des choses, vous maintenez toujours un
date
afin que vous puissiez toujours effectuer l'arithmétique des dates.la source
Je crois que ce que vous décrivez serait un remplacement direct du
datetime
module qui implémente lesdatetime.datetime
attributs (année, mois, etc.) en tant que valeurs avec une mesure d'incertitude (plutôt que de simples valeurs).Les packages Python existent pour aider avec les nombres incertains (par exemple: le package incertitudes ), et il ne serait peut-être pas trop difficile de créer un fork
datetime
qui utilise l'incertitude sur chaque attribut. Moi aussi, j'aimerais en voir un et j'aurais même pu l'utiliser. Un argument pourrait certainement être avancé en faveur de l'inclusion de audatetime
dans le paquet des incertitudes liées ci-dessus.Vos exemples seraient quelque chose comme:
Les "valeurs de signal" posent de nombreux problèmes, mais en plus, vous pouvez représenter des choses avec une incertitude que les valeurs de signal ne peuvent pas:
Une autre considération est que pour être plus précis, les incertitudes ici devraient en fait être de type
timedelta
. Je laisse comme un exercice pour le lecteur de trouver un constructeur concis et complet pourudatetime
utiliser lestimedelta
incertitudes.Donc, en fin de compte, je dirais que ce que vous décrivez est "facilement" modélisé avec des incertitudes, mais la mise en œuvre d'un
udatetime
est pratiquement assez difficile. La plupart prendront la route «facile» et diviseront le datetime en composants et suivront l'incertitude sur eux indépendamment, mais si vous vous sentez ambitieux, leuncertainties
package (ou un autre) pourrait être intéressé par une demande d'extractionudatetime
.la source
Pourquoi ne pas créer une classe "period" qui implémente une structure from to.
"Bob est né en 2000" ->
Vous pouvez ensuite implémenter diverses méthodes de recherche telles que la mise entre crochets des dates du au. L'attribut fuzz donne une indication utile de la précision de la date afin que vous puissiez spécifier fuzz == 1 pour les correspondances exactes, ou fuzz == 31 pour un mois environ.
la source