Как я могу генерировать повторяющиеся даты с помощью Python? Например, я хочу генерировать повторяющуюся дату в течение "Третьей пятницы каждого второго месяца". Я хочу генерировать повторяющиеся даты ежедневной газеты, еженедельно, ежемесячно, ежегодно (т.е. то же как функция повторения в Outlook Express).
import dateutil.rrule as dr
import dateutil.parser as dp
import dateutil.relativedelta as drel
start=dp.parse("19/02/2010") # Third Friday in Feb 2010
Это генерирует третью пятницу каждого месяца
rr = dr.rrule(dr.MONTHLY,byweekday=drel.FR(3),dtstart=start, count=10)
Это печатает каждую третью пятницу:
print map(str,rr)
# ['2010-02-19 00:00:00', '2010-03-19 00:00:00', '2010-04-16 00:00:00', '2010-05-21 00:00:00', '2010-06-18 00:00:00', '2010-07-16 00:00:00', '2010-08-20 00:00:00', '2010-09-17 00:00:00', '2010-10-15 00:00:00', '2010-11-19 00:00:00']
rr - итерация, поэтому вы можете использовать нотацию среза, чтобы выбрать любой другой элемент . Это печатает третью пятницу каждого второго месяца :
print map(str,rr[::2])
# ['2010-02-19 00:00:00', '2010-04-16 00:00:00', '2010-06-18 00:00:00', '2010-08-20 00:00:00', '2010-10-15 00:00:00']
Выше я использовал str
, чтобы немного улучшить вывод. Для более гибкого форматирования строк даты используйте strftime
: см. http://au2.php.net/strftime или страницу руководства для strftime для всех параметров.
print [d.strftime('%d/%m/%Y') for d in rr[::2]]
# ['19/02/2010', '16/04/2010', '18/06/2010', '20/08/2010', '15/10/2010']
Вы можете попробовать dateutil - особенно его relativedelta и rrule fetures.
вы можете попробовать написать это самостоятельно. сначала вам понадобится итератор, который генерирует даты, разделенные заданным интервалом:
import datetime
def dateiter(start, resolution):
date = start
while True:
yield date
date += resolution
теперь вы можете генерировать даты и фильтровать их:
# generate a list of every tuesday of february
# this iterates over every day from now, and filtered according to the rules
# warning: infinite generator below, there is nothing to end the iteration
tuesdays_of_february = (date for date in dateiter(datetime.datetime.now(), datetime.timedelta(days=1)) if date.weekday() == 4 and date.month == 2)
вы можете вызывать итератор самостоятельно, пока у вас не будет достаточно дат:
>>> next(tuesdays_of_february)
datetime.datetime(2010, 2, 19, 14, 25, 46, 171000)
теперь вам нужно ограничить результаты:
>>> from itertools import *
>>>
>>> # get the five next valid dates:
>>> list(islice(tuesdays_of_february),5)
[datetime.datetime(2010, 2,26, 14, 25, 46, 171000), datetime.datetime(2011, 2, 4
, 14, 25, 46, 171000), datetime.datetime(2011, 2, 11, 14, 25, 46, 171000), datet
ime.datetime(2011, 2, 18, 1 4, 25, 46, 171000), datetime.datetime(2011, 2, 25
, 14, 25, 46, 171000)]
>>>
>>> # or until a condition is met:
>>> list(takewhile( lambda date: date.year < 2014, tuesdays_of_february ))
[datetime.datetime(2012, 2, 3, 14, 25, 46, 171000), datetime.datetime(2012, 2, 1
0, 14, 25, 46, 171000), datetime.datetime(2012, 2, 17, 14, 25, 46, 171000), date
time.datetime(2012, 2, 24, 14, 25, 46, 171000), datetime.datetime(2013, 2, 1, 14
, 25, 46, 171000), datetime.datetime(2013, 2, 8, 14, 25, 46, 171000), datetime.d
atetime(2013, 2, 15, 14, 25, 46, 171000), datetime.datetime(2013, 2, 22, 14, 25,
46, 171000)]
не забудьте взглянуть на документацию по модулю datetime
.