Python: учитывая дату и День недели, найдите дату следующего появления данного дня недели

Это немного трудно объяснить, поэтому прошу прощения, если это не имеет смысла.

У меня есть программа где я делаю некоторые планирования. Одна из его настроек-еженедельно запускать задачу в определенные дни. Например, еженедельно по понедельникам, средам и пятницам.

Рассмотрим пример, когда текущая задача запланирована на 1/2/2012, то есть на понедельник, у меня уже есть куча кода, работающего до того момента, когда я знаю, что следующий запуск задачи должен быть на в среду после 1/2/2012. Все, что мне нужно сделать, это рассчитать фактическую дату среду (1/4/2012).

У меня на самом деле день недели, как соответствующее целое число от дата.weekday (), поэтому в этом случае у меня есть 2, который представляет среду.

что лучший способ справиться с чем-то подобным? Я чувствую, что там должно быть довольно простое решение, но оно не приходит на ум. Я думал об использовании объекта календаря для поиска, чтобы найти День я хочу неделю, но это уже перебор.

4 ответов


использовать timedelta добавить к дате. Например, используя некоторую дату d как запланированная дата для текущей задачи, и когда-нибудь next_day (далее день вы хотели бы запустить задачу).

from datetime import date, timedelta
...
n = (next_day - d.weekday()) % 7 # mod-7 ensures we don't go backward in time
next_run_date = d + timedelta(days=n)

использовать dateutil.relativedelta:

from dateutil import relativedelta
import datetime

today = datetime.date.today()
# datetime.date(2012, 1, 3)

today + relativedelta.relativedelta(weekday=2) # 2 is Wednesday
# datetime.date(2012, 1, 4)

today + relativedelta.relativedelta(weekday=6) # 6 is Sunday
# datetime.date(2012, 1, 8)

today + relativedelta.relativedelta(weekday=1) # 1 is Tuesday
# datetime.date(2012, 1, 3)
# returns today

today + relativedelta.relativedelta(weeks=1, weekday=1)
# datetime.date(2012, 1, 10)
# returns Tuesday at least one week ahead

мы знаем, что:

  • С понедельник to среда есть 2 дня разница.
  • С среда to пятница есть 2 дня разница.
  • С пятница to понедельник есть 3 дня разницы.

Итак, это так же просто, как добавление дней разницы между запланированными задачами:

from datetime import datetime, timedelta
first_scheduled_task = datetime(year=2012, month=1, day=2)
second_scheduled_task = first_scheduled_task + timedelta(2)
third_scheduled_task = second_scheduled_task + timedelta(2)
fourth_scheduled_task = third_scheduled_task + timedelta(3)

это даст нам в результате:

>>> first_scheduled_task
datetime.datetime(2012, 1, 2, 0, 0) # Monday 1/2/2012
>>> second_scheduled_task
datetime.datetime(2012, 1, 4, 0, 0) # Wednesday 1/4/2012
>>> third_scheduled_task
datetime.datetime(2012, 1, 6, 0, 0) # Friday 1/6/2012
>>> fourth_scheduled_task
datetime.datetime(2012, 1, 9, 0, 0) # Monday 1/9/2012

использовать dateutil для работы с расписанием и повторами.