Шаг 57.
Python: сборник рецептов.
Числа, даты и время. Определение даты последней пятницы

    На этом шаге мы продолжим знакомство с модулями datetime и dateutil.

Задача

    Вы хотите создать общее решение для поиска даты ближайшего прошедшего дня недели - например, последней прошедшей пятницы.

Решение

    В модуле datetime есть полезные функции и классы, которые помогают проводить такого рода вычисления. Хорошее обобщенное решение этой задачи выглядит как-то так:

>>> from datetime import datetime, timedelta
>>> weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday',
	    'Friday', 'Saturday', 'Sunday']
>>> def get_previous_byday(dayname, start_date=None):
	if start_date is None:
		start_date = datetime.today()
	day_num = start_date.weekday()
	day_num_target = weekdays.index(dayname)
	days_ago = (7 + day_num - day_num_target) % 7
	if days_ago == 0:
		days_ago = 7
	target_date = start_date - timedelta(days=days_ago)
	return target_date

    Использование этой функции в строке интерпретатора выглядит так:

>>> datetime.today() # Опорная точка
datetime.datetime(2026, 3, 31, 14, 37, 13, 441392)
>>> get_previous_byday('Monday')
datetime.datetime(2026, 3, 30, 14, 37, 25, 760234)
>>> get_previous_byday('Tuesday') # Предыдущая неделя, не сегодня
datetime.datetime(2026, 3, 24, 14, 37, 39, 187049)
>>> get_previous_byday('Friday')
datetime.datetime(2026, 3, 27, 14, 37, 54, 872791)
>>> 

    Необязательный параметр startdate может быть предоставлен с использованием другого экземпляра datetime. Например:

>>> get_previous_byday('Sunday', datetime(2012, 12, 21))
datetime.datetime(2012, 12, 16, 0, 0)
>>> 


Обсуждение

    Этот рецепт работает путем отображения стартовой и интересующей даты на номера их позиций в неделе (где понедельник - это 0). Далее используется модульная арифметика, с ее помощью мы вычисляем, сколько дней назад была нужная дата. Потом нужная дата высчитывается от стартовой даты путем вычитания соответствующего экземпляра timedelta.

    Если вы выполняете много подобных вычислений, рекомендуем установить пакет python-dateutil.


https://pypi.org/project/python-dateutil/.

    Например, вот так можно выполнить аналогичную работу с использованием функции relativedata() из модуля dateutil:

>>> from datetime import datetime
>>> from dateutil.relativedelta import relativedelta
>>> from dateutil.rrule import *
>>> d = datetime.now()
>>> print(d)
2026-03-31 14:52:56.904747
>>> # Следующая пятница
>>> print(d + relativedelta(weekday=FR))
2026-04-03 14:52:56.904747
>>>
>>> # Последняя пятница
>>> print(d + relativedelta(weekday=FR(-1)))
2026-03-27 14:52:56.904747
>>>

    На следующем шаге мы рассмотрим поиск диапазона дат для текущего месяца.




Предыдущий шаг Содержание