Quiero poder capturar hechos como Bob was born in 2000
y Bill's birthday is May 7th
.
En ambos ejemplos, solo conocemos parte de la fecha de nacimiento de la persona. En un caso sabemos solo el año; en el otro caso sabemos el mes y el día, pero no el año.
¿Cómo capturo esta información?
Algunos ejemplos de cómo podría funcionar esto:
Imagine una biblioteca como datetime que permitiera a None en los campos representar incógnitas. Podría tener un código como el siguiente:
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 es solo un ejemplo de cómo podría comportarse. No necesariamente quiero este comportamiento preciso.
Respuestas:
En primer lugar, una vez que comienza a descomponer las fechas en sus componentes constituyentes, ya no son fechas.
De la misma manera que no es posible eliminar la funcionalidad a través de subclases sin romper OOP, no es posible mezclar fechas y fracciones de fecha sin causar confusión (o peor) haciéndolas compatibles como en su ejemplo de código sin romper otra cosa.
Si desea capturar un año, ¿qué tiene de malo un objeto que contenga un entero simple? Si desea capturar un mes y un día, ¿por qué no capturar una enumeración mensual y un día entero? Tal vez incluso los almacene internamente en un objeto de fecha para obtener la verificación de límites adecuada (por ejemplo, el 31 de febrero no tiene sentido). Exponer una interfaz diferente, sin embargo.
¿Por qué querrías comparar una fecha con un año para ver si son iguales, mayores o menores? No tiene sentido: no hay información suficiente para hacer esa comparación. Sin embargo, hay otras comparaciones que podrían tener sentido (este es un pseudocódigo):
fuente
El segundo comentario de Robert Harvey contiene la respuesta correcta, pero permítanme ampliarlo un poco.
El año de nacimiento de las personas y las fechas de nacimiento de las personas son entidades completamente diferentes, por lo que no es necesario (y en realidad no debería) usar el mismo mecanismo para ambos.
Para las fechas de nacimiento, puede idear un
BirthDate
tipo de datos (o posiblemente,YearlyRecurringDate
aunque no puedo encontrar un nombre decente en este momento) que solo contenga undate
año constante, como 2000 por convención. El año 2000 es una buena opción porque fue un salto, por lo que no le fallará a las personas cuyo cumpleaños es el 28 de febrero.Durante años de nacimiento, se puede idear un
BirthYear
tipo de datos (o posiblemente unApproximateDate
tipo de datos) que contendrá unadate
, y un indicador de la precisión:Year
,Month
,Full
.El beneficio de estos enfoques es que, en el fondo de las cosas, aún se mantiene una,
date
por lo que aún se puede realizar la aritmética de fechas.fuente
Creo que lo que está describiendo sería un reemplazo directo para el
datetime
módulo que implementa losdatetime.datetime
atributos (año, mes, etc.) como valores con una medición de incertidumbre (en lugar de solo valores).Los paquetes de Python existen para ayudar con números inciertos (por ejemplo: el paquete de incertidumbres ), y quizás no sería demasiado difícil hacer una bifurcación
datetime
que usa incertidumbre en cada atributo. A mí también me gustaría ver uno e incluso podría haberlo usado. Ciertamente, se podría argumentar la inclusión de unudatetime
paquete de incertidumbres anteriormente relacionado.Sus ejemplos serían algo como:
Los "valores de señal" tienen muchos problemas, pero además puede representar cosas con incertidumbre que los valores de señal no pueden:
Otra consideración es que para ser más precisos, las incertidumbres aquí deberían ser de tipo
timedelta
. Lo dejo como un ejercicio para que el lector descubra un constructor conciso y completo paraudatetime
usartimedelta
incertidumbres.Así que, en última instancia, diría que lo que usted describe se modela "fácilmente" con incertidumbres, pero la implementación de a
udatetime
es prácticamente bastante difícil. La mayoría tomará la ruta "fácil" y dividirá la fecha y hora en componentes y rastreará la incertidumbre sobre ellos de manera independiente, pero si se siente ambicioso, eluncertainties
paquete (u otro) podría estar interesado en una solicitud de extracciónudatetime
.fuente
¿Por qué no crear una clase "período" que implemente una estructura desde?
"Bob nació en 2000" ->
Luego puede implementar varios métodos de búsqueda, entre corchetes desde las fechas. El atributo fuzz proporciona una indicación útil de cuán precisa es la fecha para que pueda especificar fuzz == 1 para coincidencias exactas, o fuzz == 31 para dentro de un mes más o menos.
fuente