Звучит так, как будто вы хотите сохранить интервал дат. В Python это (насколько я все еще немного понимаю) легче всего реализовать, храня два объекта datetime.datetime, один из которых указывает начало диапазона дат, а другой - конец. Подобным образом, который используется для указания фрагментов списка, конечная точка сама не будет включена в диапазон дат.
Например, этот код будет реализовывать диапазон дат в виде именованного кортежа:
>>> from datetime import datetime
>>> from collections import namedtuple
>>> DateRange = namedtuple('DateRange', 'start end')
>>> the_year_2010 = DateRange(datetime(2010, 1, 1), datetime(2011, 1, 1))
>>> the_year_2010.start <= datetime(2010, 4, 20) < the_year_2010.end
True
>>> the_year_2010.start <= datetime(2009, 12, 31) < the_year_2010.end
False
>>> the_year_2010.start <= datetime(2011, 1, 1) < the_year_2010.end
False
Или даже добавить немного магии:
>>> DateRange.__contains__ = lambda self, x: self.start <= x < self.end
>>> datetime(2010, 4, 20) in the_year_2010
True
>>> datetime(2011, 4, 20) in the_year_2010
False
Это настолько полезная концепция, что я уверен, что кто-то уже сделал реализацию доступной. Например, быстрый взгляд показывает, что класс relativedate
из пакета dateutil сделает это и, более выразительно, разрешит передачу ключевого аргумента 'years' в конструктор.
Однако отображение такого объекта в полях базы данных несколько сложнее, поэтому вам может быть лучше реализовать его, просто потянув оба поля по отдельности, а затем объединяя их. Я думаю, это зависит от структуры БД; Я еще не очень знаком с этим аспектом Python.
В любом случае, я думаю, что ключом к пониманию «частичной даты» является диапазон, а не просто значение.
редактировать
Заманчиво, но я считаю неуместным добавлять больше магических методов, которые будут обрабатывать использование операторов >
и <
. Там есть некоторая двусмысленность: встречается ли дата, которая «больше чем» данного диапазона, после конца диапазона или после его начала? Изначально представляется целесообразным использовать <=
, чтобы указать, что дата в правой части уравнения находится после начала диапазона, и <
, чтобы указать, что это после конца.
Однако это подразумевает равенство между диапазоном и датой в пределах диапазона, что неверно, поскольку подразумевает, что месяц май 2010 года равен году 2010, потому что 4 мая 2010 года равняется обоим их. То есть вы бы в конечном итоге получили фальсизмы типа 2010-04-20 == 2010 == 2010-05-04
, которые были бы правдой.
Так что, вероятно, было бы лучше реализовать метод, подобный isafterstart
, чтобы явно проверить, находится ли дата после начала диапазона. Но, опять же, кто-то, вероятно, уже сделал это, поэтому, вероятно, стоит взглянуть на pypi , чтобы увидеть, что считается готовым к производству. На это указывает наличие «Статус разработки :: 5 - Производство / Стабильный» в разделе «Категории» на странице pypi данного модуля. Обратите внимание, что не всем модулям присвоен статус разработки.
Или вы можете просто упростить и, используя базовую реализацию namedtuple, явно проверить
>>> datetime(2012, 12, 21) >= the_year_2010.start
True