Python: с учетом даты и дня недели найдите дату следующего вхождения данного дня недели - PullRequest
9 голосов
/ 03 января 2012

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

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

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

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

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

Ответы [ 4 ]

13 голосов
/ 03 января 2012

Использование 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
8 голосов
/ 03 января 2012

Используйте 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)
0 голосов
/ 03 января 2012

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

0 голосов
/ 03 января 2012

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

  • с понедельник до среда есть 2 дня разницы.
  • с среда до Пятница разница в 2 дня.
  • с Пятница до Понедельник разница в 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
...