Перейти к содержанию

412 уроков, 25 библиотек и челлендж «Что выведет код?» — бесплатно, код прямо в браузере

Начать обучение
Урок 12 из 20 Начальный 20 мин 120 XP

weekday и isoweekday: дни недели

weekday() считает с нуля: 0 — понедельник. isoweekday() — с единицы, по стандарту ISO-8601. Достаём день недели из даты, переводим в «среду» и находим ближайший понедельник.

Редакция Питоники

У любой даты можно спросить, каким днём недели она была. В модуле datetime для этого два метода-близнеца: weekday и isoweekday. Спросим их у 21 октября 2026 года.

два метода, одна дата
from datetime import date

d = date(2026, 10, 21)
print(d.weekday())
print(d.isoweekday())
Вывод
2
3

21 октября 2026 — среда, и обе цифры про неё говорят, но с разных точек отсчёта. weekday() ведёт отсчёт с нуля: 0 — понедельник, 6 — воскресенье, а isoweekday() считает по ISO-8601 с единицы. isoweekday всегда ровно на единицу больше weekday: одна и та же среда — это 2 и 3.

День неделиweekday()isoweekday()
понедельник01
вторник12
среда23
четверг34
пятница45
суббота56
воскресенье67

День недели по-русски

Ни weekday, ни isoweekday не возвращают имя дня — только номер. Имена хранят своим списком: в Python списки индексируются с нуля, так что порядок от понедельника идеально совпадает со шкалой weekday. Индекс передаётся без вычислений: weekday дал 2 — RU_DAYS[2] это среда. С isoweekday понадобился бы минус единица: RU_DAYS[d.isoweekday() - 1]. Главная ловушка — написать список с воскресенья: тогда каждый день недели будет сдвинут. Держите порядок от понедельника — тот же, в котором шкалы идут в таблице выше.

среда по-русски
from datetime import date

RU_DAYS = ['понедельник', 'вторник', 'среда', 'четверг', 'пятница', 'суббота', 'воскресенье']

d = date(2026, 10, 21)
print(RU_DAYS[d.weekday()])
Вывод
среда
неделя целиком
from datetime import date, timedelta

d = date(2026, 10, 19)
for i in range(7):
    day = d + timedelta(days=i)
    print(day, day.weekday(), day.isoweekday())
Вывод
2026-10-19 0 1
2026-10-20 1 2
2026-10-21 2 3
2026-10-22 3 4
2026-10-23 4 5
2026-10-24 5 6
2026-10-25 6 7

Ближайший понедельник через timedelta

от среды до понедельника
from datetime import date, timedelta

d = date(2026, 10, 21)
days_ahead = (0 - d.weekday()) % 7
monday = d + timedelta(days=days_ahead)
print(days_ahead)
print(monday)
Вывод
5
2026-10-26

Формула (0 - d.weekday()) % 7 считает, через сколько дней наступит ближайший понедельник: 0 здесь — номер понедельника в шкале weekday, вычитание даёт сдвиг, а % 7 заворачивает отрицательный сдвиг в положительный. Для среды вышло 5 дней — 21 плюс 5 это 26 октября. Для самого понедельника формула дала бы 0: дата не сдвинулась бы, ближайший понедельник и есть сегодня. Дальше — timestamp: превращаем даты в числа и обратно.

Границы недели: от понедельника до воскресенья

Знание номера дня недели редко бывает нужным само по себе. Гораздо чаще требуется найти границы: где началась неделя и где она закончится. Ответ строится на арифметике с timedelta. Отступ назад равен weekday(), потому что у понедельника номер 0, у среды 2, и ровно столько дней надо отступить назад. Вперёд отступают на шесть дней, потому что неделя содержит семь дней, а нумерация начинается с нуля.

week_bounds.py — понедельник и воскресенье
from datetime import date, timedelta

d = date(2026, 10, 21)
monday = d - timedelta(days=d.weekday())
sunday = monday + timedelta(days=6)

print(monday)
print(sunday)
Вывод
2026-10-19
2026-10-25

Приём хорош тем, что работает с любой датой без ветвлений: и для среды, и для самого понедельника. В последнем случае отступ равен нулю, и границы сходятся с исходной датой. Такие вычисления мы используем в отчётности за неделю и в расчёте рабочих дней, о котором пойдёт речь в уроке 17.

Рабочий день или выходной

Следующая задача — отличить будни от выходных. С isoweekday всё решается сравнением: суббота это 6, воскресенье 7, а будни — от 1 до 5. Порог «больше либо равно 6» работает и на других языках, потому что шкала ISO отсчитывает неделю с понедельника. Наивная проверка через weekday() выглядит иначе: там суббота это 5, и воскресенье 6, так что условие принимает вид больше либо равно 5.

workweek.py — будни и выходные
from datetime import date, timedelta

d = date(2026, 10, 19)

for i in range(7):
    day = d + timedelta(days=i)
    kind = 'выходной' if day.isoweekday() >= 6 else 'рабочий'
    print(day, kind)
Вывод
2026-10-19 рабочий
2026-10-20 рабочий
2026-10-21 рабочий
2026-10-22 рабочий
2026-10-23 рабочий
2026-10-24 выходной
2026-10-25 выходной
index_error.py — воскресенье не влезло в список
from datetime import date

RU_DAYS = ['понедельник', 'вторник', 'среда', 'четверг', 'пятница', 'суббота', 'воскресенье']

d = date(2026, 10, 25)

try:
    print(RU_DAYS[d.isoweekday()])
except IndexError:
    print('isoweekday даёт 7, а список индексируется с 0')
Вывод
isoweekday даёт 7, а список индексируется с 0

Договорённость, которую стоит записать один раз и не нарушать: список дней недели всегда начинается с понедельника, и в код попадает именно weekday(). Если в команде появляется второй список, начинающийся с воскресенья, — это не ошибка формата, а рассинхронизация, которая обнаружится через месяц в чужом отчёте.

Номер недели: тот же вопрос, другой ответ

День недели и неделя — разные вещи, и их часто путают, потому что слова похожие. Номер недели считается отдельно, и считать его можно двумя способами. Коды %U и %W в strftime дают неделю по календарю, а метод isocalendar() отдаёт неделю по ISO-8601 вместе с годом и днём недели. Для отчётов по ISO-неделям второй вариант удобнее: он сразу возвращает кортеж.

iso_week.py — неделя по ISO-8601
from datetime import date

d = date(2026, 10, 21)
year, week, weekday = d.isocalendar()

print(year, week, weekday)
Вывод
2026 43 3

Третье число в кортеже — это день недели по ISO-шкале, то есть от 1 до 7, где понедельник это 1. Со шкалой weekday() ничего общего, кроме самого дня. Если вы печатаете отчёт по неделям, а где-то в коде дни нумеруются по-разному, получится расхождение в день, которое видно не сразу. Про полную шпаргалку кодов, включая %U, %W, %V и %G, — в уроке 8.

weekday() ведёт отсчёт с нуля, isoweekday() — с единицы, и обе шкалы начинают неделю с понедельника: разница между ними ровно в том, откуда пошло отсчитывание.

weekday и isoweekday: два ответа на один вопрос

У дня недели в Python два представления, и путаница между ними — источник ошибок на целый день: weekday() возвращает номер от 0 (понедельник) до 6 (воскресенье), а isoweekday() — от 1 (понедельник) до 7 (воскресенье).

Разница видна на воскресенье: у него weekday() даёт 6, а isoweekday() — 7. Если вы сравниваете с магическим числом 7, проверяйте, какое представление имеете в виду.

Для календарей и отчётов по ISO-неделям правильнее isoweekday(): он совпадает с нумерацией ISO 8601, по которой неделя идёт с понедельника, и люди обычно имеют в виду именно её. Для индексации массива с нуля удобнее weekday() — индекс не выходит за границы списка.

И полезная деталь, на которой спотыкаются при отчётах за неделю: номер недели по ISO считается не от первого января, а так, что первой считается неделя с первым четвергом года. Из-за этого в начале календарного года номер недели может быть 52 или 53, а год по ISO — не тот, что на календаре. 1 января 2027 года по ISO относится к 53-й неделе 2026 года, и это не опечатка, а правило. Считать недели делением на 7 нельзя — используйте isocalendar(), он отдаёт готовую тройку (год, неделя, день).

iso_year.py — год по ISO может отличаться от календарного
from datetime import date

d = date(2027, 1, 1)
year, week, weekday = d.isocalendar()

print(d)
print(year, week, weekday)
print(d.strftime('%V'))
Вывод
2027-01-01
2026 53 5
53

Тут же видно и расхождение с кодами strftime: %V даёт тот же 53, а вот %U и %W для этой даты дают 00 — они считают недели от первого января по своему правилу, с воскресенья и с понедельника соответственно. Три разных ответа на вопрос «какая сейчас неделя», и разница между ними видна как раз на границах года. Отсюда простое правило: не смешивайте %U, %W и %V в одном отчёте и всегда пишите, по какой шкале считаете.

Что выведет код?

Сначала предскажи ответ в голове — это главный навык программиста.

from datetime import date

print(date(2026, 10, 25).weekday())
from datetime import date

print(date(2026, 10, 25).isoweekday())
from datetime import date

RU_DAYS = ['понедельник', 'вторник', 'среда', 'четверг', 'пятница', 'суббота', 'воскресенье']

d = date(2026, 10, 24)
print(RU_DAYS[d.weekday()])
from datetime import date, timedelta

d = date(2026, 10, 21)
monday = d - timedelta(days=d.weekday())
sunday = monday + timedelta(days=6)

print(monday)
print(sunday)
Проверь себя
0 / 8

1. Что вернёт weekday() для воскресенья?

2. Чем isoweekday отличается от weekday?

3. Как получить русское имя дня недели из даты?

4. Что вернёт (0 - date(2026, 10, 21).weekday()) % 7 для среды?

5. weekday() вернул 3 для 1 января 2026 года. Какой это день?

6. Как найти дату понедельника той недели, в которую попала заданная дата?

7. Как проверить по ISO-шкале, что день выходной?

8. Что произойдёт при RU_DAYS[d.isoweekday()] для воскресенья, если список начинается с понедельника?

Карточки терминов
Запомнено: 0 / 9
Практика

Возьмите дату date(2026, 1, 1). Выведите три строки: номер дня по weekday(), номер по isoweekday() и имя дня по-русски из списка RU_DAYS.

practice.py
Вопросы и ответы по уроку

Как узнать день недели по дате в Python?

Методом d.weekday() — он вернёт номер от 0 (понедельник) до 6 (воскресенье), либо d.isoweekday() — от 1 до 7 по ISO-8601. Для имени дня по-русски заведите список RU_DAYS и возьмите элемент RU_DAYS[d.weekday()].

Почему weekday в Python начинается с нуля?

Потому что это обычный индекс списка: 0 — понедельник, 6 — воскресенье. Такая шкала совпадает с индексацией списков, поэтому русское имя дня достаётся без арифметики: RU_DAYS[d.weekday()].

Чем isoweekday лучше weekday?

Ничем не лучше — это та же информация в шкале ISO-8601, где недели нумеруются с 1, а воскресенье получает номер 7. Шкала ISO удобна для обмена данными с другими системами; внутри Python-кода чаще используют weekday из-за совместимости со списками.

Как найти дату ближайшего понедельника?

Формулой (0 - d.weekday()) % 7 посчитайте, через сколько дней наступит понедельник, и прибавьте timedelta(days=...): для среды выйдет 5 дней, для самого понедельника — 0. В Python остаток всегда неотрицательный, поэтому формула не ломается во второй половине недели.

Урок 13: timestamp

Как найти понедельник и воскресенье недели, в которую попала дата?

Отступите назад на d.weekday() дней — столько, сколько дней прошло с понедельника: monday = d - timedelta(days=d.weekday()). Воскресенье — это понедельник плюс шесть дней. Формула работает для любого дня, включая сам понедельник.

Как проверить, что дата выходная?

По ISO-шкале: isoweekday() >= 6 — это суббота и воскресенье. По шкале weekday порог другой: >= 5, потому что там суббота имеет номер 5, а воскресенье 6. Перепутать шкалы легко, поэтому выберите одну и используйте её везде.

Урок 17: рабочие дни

Почему RU_DAYS[d.isoweekday()] ломается на воскресенье?

isoweekday() отдаёт 7 для воскресенья, а список из семи дней индексируется с нуля до 6. Отсюда IndexError. Со списком, начинающимся с понедельника, совместим только weekday: он даёт 6 для воскресенья.

Понравился урок? Сошлитесь на него

«weekday() ведёт отсчёт с нуля: 0 — понедельник, 6 — воскресенье, а isoweekday() считает по ISO-8601 с единицы.»

Скопируйте готовую ссылку в формате HTML, Markdown или чистый адрес и вставьте в статью на Habr, VC, Telegram-канал или свой блог — так о проекте узнают новые читатели.

TelegramVK

Что дальше

Осталось в разделе: 20 из 20. Прогресс хранится в вашем браузере.

Похожие уроки по темам

Подобраны автоматически по пересечению тем и ключевых слов.