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() |
|---|---|---|
| понедельник | 0 | 1 |
| вторник | 1 | 2 |
| среда | 2 | 3 |
| четверг | 3 | 4 |
| пятница | 4 | 5 |
| суббота | 5 | 6 |
| воскресенье | 6 | 7 |
День недели по-русски
Ни 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, и ровно столько дней надо отступить назад. Вперёд отступают на шесть дней, потому что неделя содержит семь дней, а нумерация начинается с нуля.
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.
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 выходной
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-неделям второй вариант удобнее: он сразу возвращает кортеж.
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(), он отдаёт готовую тройку (год, неделя, день).
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)
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()] для воскресенья, если список начинается с понедельника?
Возьмите дату date(2026, 1, 1). Выведите три строки: номер дня по weekday(), номер по isoweekday() и имя дня по-русски из списка RU_DAYS.
Как узнать день недели по дате в 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-канал или свой блог — так о проекте узнают новые читатели.
Что дальше
Осталось в разделе: 20 из 20. Прогресс хранится в вашем браузере.
Что читать дальше
Datetime · Урок 11
combine и replace: datetime из частей
date знает день, time знает часы — combine склеивает их в datetime, а replace меняет отдельные поля и возвращает новый объект: datetime неизменяем.
Datetime · Урок 13
timestamp: unix-время и эпоха 1970
Unix-время — число секунд с полуночи 1 января 1970 года по UTC. Считаем timestamp у aware-дат, переводим число обратно через fromtimestamp — и всегда указываем пояс.
Похожие уроки по темам
Подобраны автоматически по пересечению тем и ключевых слов.
openpyxl · Урок 9
Даты в Excel через openpyxl: запись, формат и арифметика
Пишем в ячейку настоящий datetime, показываем его по-русски маской DD.MM.YYYY и считаем дни между датами — а заодно узнаём, почему дату из файла нельзя сравнивать со строкой.
openpyxl datetimetimedelta python дни
Циклы · Урок 5
Цикл while в Python: повторять, пока условие
while повторяет тело, пока условие верно: число шагов заранее неизвестно. Разбираем проверку условия, шаг к выходу и главный риск — бесконечный цикл.
while и for разница python
Datetime · Урок 15
calendar: месяц и год в текст
Модуль calendar рисует месяц одной строкой, говорит, каким днём недели была дата, проверяет год на високосность и сообщает размер месяца — без единого объекта datetime.
calendar weekday pythonpython день недели по дате