Вот полная функция генератора, основанная на решении из @sth. Он включает в себя решающее исправление, которое было упомянуто в комментариях к его решению.
Вы можете указать день недели (используя индексацию Python с 0 = понедельник до 6 = воскресенье), дату начала и количество недель для перечисления.
def get_all_dates_of_day_of_week_in_year(day_of_week, start_year, start_month,
start_day, max_weeks=None):
'''
Generator function to enumerate all calendar dates for a specific day
of the week during one year. For example, all Wednesdays in 2018 are:
1/3/2018, 1/10/2018, 1/17/2018, 1/24/2018, 1/31/2018, 2/7/2018, etc.
Parameters:
----------
day_of_week : int
The day_of_week should be one of these values: 0=Monday, 1=Tuesday,
2=Wednesday, 3=Thursday, 4=Friday, 5=Saturday, 6=Sunday.
start_year : int
start_month : int
start_day : int
The starting date from which to list out all the dates
max_weeks : int or None
If None, then list out all dates for the rest of the year.
Otherwise, end the list after max_weeks number of weeks.
'''
if day_of_week < 0 or day_of_week > 6:
raise ValueError('day_of_week should be in [0, 6]')
date_iter = date(start_year, start_month, start_day)
# First desired day_of_week
date_iter += timedelta(days=(day_of_week - date_iter.weekday() + 7) % 7)
week = 1
while date_iter.year == start_year:
yield date_iter
date_iter += timedelta(days=7)
if max_weeks is not None:
week += 1
if week > max_weeks:
break
Пример использования для получения всех сред, начиная с 1 января 2018 года, в течение 10 недель.
import calendar
day_of_week = 2
max_weeks = 10
for d in get_all_dates_of_day_of_week_in_year (day_of_week, 2018, 1, 1, max_weeks):
print "%s, %d/%d/%d" % (calendar.day_name[d.weekday()], d.year, d.month, d.day)
Приведенный выше код выдает:
Wednesday, 2018/1/3
Wednesday, 2018/1/10
Wednesday, 2018/1/17
Wednesday, 2018/1/24
Wednesday, 2018/1/31
Wednesday, 2018/2/7
Wednesday, 2018/2/14
Wednesday, 2018/2/21
Wednesday, 2018/2/28
Wednesday, 2018/3/7