Вспомните: в прошлом уроке вы научили программу не падать на плохих данных — try/except ловит ValueError, когда в столбце суммы вместо числа стоит «сто». В таблице расходов из главы 1 есть ещё один столбец, с которым мы до сих пор обращались как с простым текстом: дата. "29.09" — это строка, и Python не знает, что до "01.10" от неё два дня.
🎯 После урока сможете: превратить дату из таблицы (29.09.2026 или 2026-09-29) в объект Python, посчитать, сколько дней осталось до срока, сложить расходы по месяцам и пропустить строку с несуществующей датой, не уронив программу.
date: день как объект, а не строка
В стандартном модуле datetime живут четыре нужных нам класса: date (день), datetime (день и время), timedelta (промежуток) и time (время суток, в этом уроке почти не понадобится). Устанавливать ничего не нужно, достаточно импорта.
from datetime import date
d = date(2026, 9, 29) # год, месяц, день
print(d)
print(d.year, d.month, d.day)
print(d.weekday()) # 0 — понедельник, 6 — воскресенье
2026-09-29
2026 9 29
1
date(год, месяц, день)— порядок именно такой, от большего к меньшему.printпоказывает дату в международном видеГГГГ-ММ-ДД.year,month,day— части даты, уже числа,int()не нужен.weekday()— номер дня недели с нуля: 0 — понедельник, 1 — вторник, … 6 — воскресенье.- Несуществующую дату создать нельзя:
date(2026, 9, 31)сразу дастValueError.
Главное отличие от строки — даты правильно сравниваются. Строки сравниваются по буквам слева направо, поэтому "29.09" «больше» "01.10": символ 2 идёт после 0. С датами такой ошибки нет:
from datetime import date
print("29.09" < "01.10") # строки
print(date(2026, 9, 29) < date(2026, 10, 1)) # даты
False
True
Проверьте себя
Задание. Что выведет программа? Введите True или False.
Исходный код для этого задания:
from datetime import date print(date(2026, 9, 29) < date(2026, 9, 3))Подсказка: Сравниваются не строки, а даты: какой день в сентябре наступает раньше?
✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.
Онлайн-проверка ответа появится позже
Задание. Что выведет программа? Введите число.
Исходный код для этого задания:
from datetime import date d = date(2026, 10, 4) print(d.weekday())Подсказка: Отсчёт с нуля: 0 — понедельник. Если не знаете, на какой день недели выпадает 4 октября 2026 года, запустите код у себя.
✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.
Онлайн-проверка ответа появится позже
timedelta: сколько дней до срока
Вычтите одну дату из другой — получите не число, а объект timedelta, промежуток между ними. Число дней лежит в его атрибуте days.
from datetime import date
today = date(2026, 9, 29)
deadline = date(2026, 10, 15) # оплатить интернет
left = deadline - today
print(left)
print(left.days)
16 days, 0:00:00
16
В обратную сторону: к дате можно прибавить промежуток. timedelta принимает days, weeks, hours, minutes, seconds. Переход через конец месяца и високосные годы Python считает сам.
from datetime import date, timedelta
paid = date(2026, 9, 29)
print(paid + timedelta(days=30)) # следующий платёж
print(paid - timedelta(weeks=2)) # две недели назад
2026-10-29
2026-09-15

Проверьте себя
Задание. Сколько дней от 30 сентября до Нового года (31 декабря)? Программа ниже это считает. Введите число, которое она выведет.
Исходный код для этого задания:
from datetime import date left = date(2026, 12, 31) - date(2026, 9, 30) print(left.days)Подсказка: Вычитание дат даёт timedelta, .days — целое число дней. Можно посчитать дни в октябре, ноябре и декабре или запустить код.
✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.
Онлайн-проверка ответа появится позже
Задание. Что выведет программа? Введите дату ровно в том виде, как её напечатает print.
Исходный код для этого задания:
from datetime import date, timedelta print(date(2026, 9, 29) + timedelta(days=5))Подсказка: print показывает дату как ГГГГ-ММ-ДД. Не забудьте, что в сентябре 30 дней.
✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.
Онлайн-проверка ответа появится позже
Задание. Срок оплаты был раньше сегодняшнего дня. Что выведет программа? Введите число со знаком, если он есть.
Исходный код для этого задания:
from datetime import date today = date(2026, 9, 29) deadline = date(2026, 9, 24) print((deadline - today).days)Подсказка: Из какой даты вычитают какую? Если из ранней вычесть позднюю, знак будет минус.
✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.
Онлайн-проверка ответа появится позже
Задание. Список сроков по счетам. Программа считает, сколько счетов уже просрочено на 30 сентября 2026 года. Что она выведет? Введите число.
Исходный код для этого задания:
from datetime import date today = date(2026, 9, 30) deadlines = [date(2026, 9, 25), date(2026, 10, 1), date(2026, 9, 30), date(2026, 8, 31), date(2026, 10, 15), date(2026, 9, 29)] late = 0 for d in deadlines: if (d - today).days < 0: late += 1 print(late)Подсказка: Просрочен счёт, у которого разность (срок − сегодня) меньше нуля. Срок «сегодня» даёт ноль — он не просрочен.
✅ Готово, если: программа запускается без ошибок и выводит то, что просят в задании.
Онлайн-проверка ответа появится позже
datetime: когда важны часы и минуты
datetime — это дата плюс время. Разность двух datetime — тот же timedelta, только теперь в нём есть и часы. Сколько всего секунд в промежутке, говорит метод total_seconds(); поделите на 3600 — получите часы, на 60 — минуты.
from datetime import datetime
start = datetime(2026, 9, 29, 9, 15) # год, месяц, день, часы, минуты
end = datetime(2026, 9, 29, 18, 45)
work = end - start
print(work)
print(work.total_seconds() / 3600)
print(end.date()) # только дата, без времени
9:30:00
9.5
2026-09-29
- Атрибут
secondsуtimedelta— не «всего секунд», а остаток внутри неполных суток. Для полного числа беритеtotal_seconds(). datetime.now()иdate.today()дают текущий момент и сегодняшний день. В своих программах пользуйтесь ими; в примерах и заданиях курса даты заданы явно, чтобы ответ у всех совпадал.
Проверьте себя
Задание. Поездка на такси началась в 23:30 и закончилась в 01:00 следующего дня. Что выведет программа? Введите число так, как его напечатает Python.
Исходный код для этого задания:
from datetime import datetime start = datetime(2026, 9, 29, 23, 30) end = datetime(2026, 9, 30, 1, 0) print((end - start).total_seconds() / 60)Подсказка: total_seconds() — все секунды промежутка, деление на 60 переводит их в минуты. Деление / в Python даёт дробное число.
✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.
Онлайн-проверка ответа появится позже
strptime: из строки в дату
Даты в таблице приходят строками: "29.09.2026" из русского Excel или "2026-09-29" из выгрузки банка. Превратить строку в дату умеет datetime.strptime(строка, формат) (p — parse, «разобрать»). Формат — шаблон, где на месте частей даты стоят коды со знаком %, а всё остальное (точки, дефисы, двоеточия) должно совпасть со строкой буква в букву.

from datetime import datetime
d1 = datetime.strptime("29.09.2026", "%d.%m.%Y")
d2 = datetime.strptime("2026-09-29", "%Y-%m-%d")
print(d1)
print(d1 == d2)
print(d1.date())
2026-09-29 00:00:00
True
2026-09-29
strptime всегда возвращает datetime, поэтому в выводе появилось 00:00:00. Нужен только день — возьмите .date().
В таблице расходов из главы 1 даты записаны без года: "29.09". Разбирать такую строку через strptime напрямую не стоит: году неоткуда взяться, новые версии Python предупреждают об этом, а в будущих это станет ошибкой. Надёжный приём — приклеить год к строке и разбирать полную дату. А поменять часть уже готовой даты можно методом replace: он возвращает копию даты с заменённой частью, например с другим годом.
from datetime import datetime
s = "29.09"
d = datetime.strptime(s + ".2026", "%d.%m.%Y")
print(d.date())
next_year = d.replace(year=2027)
print(next_year.date())
2026-09-29
2027-09-29
Проверьте себя
Контрольный вопрос. В выгрузке из банка даты выглядят так: 2026-09-29. Какой формат передать в strptime? Выберите вариант.
Подсказка: Сверьте шаблон со строкой слева направо: что стоит первым, какие разделители, какой код отвечает за месяц, а какой — за минуты.
Онлайн-проверка ответа появится позже
Задание. В таблице дата записана без года, и программа приклеивает год к строке. Что она выведет? Введите дату ровно так, как её напечатает print.
Исходный код для этого задания:
from datetime import datetime s = "05.10" d = datetime.strptime(s + ".2026", "%d.%m.%Y") print(d.date())Подсказка: Сначала склейте строку целиком и сопоставьте её части с кодами шаблона. print для даты показывает ГГГГ-ММ-ДД.
✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.
Онлайн-проверка ответа появится позже
Задание. Ежегодный платёж за домен — 15 марта. Программа находит дату следующего платежа. Что она выведет? Введите дату ровно так, как её напечатает print.
Исходный код для этого задания:
from datetime import date paid = date(2026, 3, 15) next_paid = paid.replace(year=paid.year + 1) print(next_paid)Подсказка: replace меняет только указанную часть даты, остальные остаются прежними.
✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.
Онлайн-проверка ответа появится позже
Задание. Программист перепутал местами день и месяц в формате. Что выведет программа? Введите число.
Исходный код для этого задания:
from datetime import datetime d = datetime.strptime("05.10.2026", "%m.%d.%Y") print(d.month)Подсказка: Сопоставьте части строки с кодами шаблона по порядку: первое число попадает в %m.
✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.
Онлайн-проверка ответа появится позже
strftime: из даты в строку
Обратная операция — strftime(формат) (f — format): дата превращается в строку по тому же шаблону кодов. Так печатают дату по-русски и так же получают «ключ месяца» для группировки: %Y-%m даёт "2026-09", одинаковый для всех дней сентября.
from datetime import datetime
d = datetime(2026, 9, 29, 18, 45)
print(d.strftime("%d.%m.%Y"))
print(d.strftime("%d.%m.%Y %H:%M"))
print(d.strftime("%Y-%m"))
29.09.2026
29.09.2026 18:45
2026-09
Типичный путь данных: прочитали строку в одном формате через strptime, записали в другом через strftime.
from datetime import datetime
bank = "2026-10-03"
d = datetime.strptime(bank, "%Y-%m-%d")
print(d.strftime("%d.%m.%Y"))
03.10.2026
- Код
%Aпечатает день недели, но на языке системы — у многих этоTuesday. Надёжнее свой список:["пн", "вт", "ср", "чт", "пт", "сб", "вс"][d.weekday()]. - Строки вида
"2026-09"сортируются правильно и как текст: год стоит первым, месяц — двумя цифрами. Поэтому для ключей и имён файлов удобен именно этот порядок.
Проверьте себя
Задание. Что выведет программа? Введите строку ровно так, как её напечатает print.
Исходный код для этого задания:
from datetime import date d = date(2026, 10, 5) print(d.strftime("%d.%m"))Подсказка: %d и %m дают по две цифры, точка между ними переносится как есть.
✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.
Онлайн-проверка ответа появится позже
Задание. Программа переводит дату из формата банка в русский. Что она выведет? Введите строку ровно так, как её напечатает print.
Исходный код для этого задания:
from datetime import datetime s = "2026-11-03" d = datetime.strptime(s, "%Y-%m-%d") print(d.strftime("%d.%m.%Y"))Подсказка: Сначала разберите строку по первому шаблону: где год, где месяц, где день. Потом соберите по второму.
✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.
Онлайн-проверка ответа появится позже
Плохая дата: ValueError и try/except
Если строка не подходит под шаблон или такого дня нет в календаре, strptime бросает ValueError. В таблице, которую заполняли руками, так бывает постоянно: 31 сентября, лишний пробел, дата в другом формате. Из прошлого урока вы знаете, что делать: ловить исключение и пропускать строку.
from datetime import datetime
dates = ["29.09.2026", "31.09.2026", "2026-09-30", "01.10.2026"]
for s in dates:
try:
d = datetime.strptime(s, "%d.%m.%Y")
except ValueError:
print("Пропускаю", s, "— ValueError")
continue
print("Ок", d.date())
Ок 2026-09-29
Пропускаю 31.09.2026 — ValueError
Пропускаю 2026-09-30 — ValueError
Ок 2026-10-01
Обе плохие строки дали один тип ошибки — ValueError, хотя причины разные: 31 сентября нет в календаре, а 2026-09-30 не похожа на шаблон. Если поймать исключение через as e и напечатать e, как в прошлом уроке, сообщение назовёт причину. Точный текст сообщения зависит от версии Python, поэтому ориентируйтесь на тип ошибки, а сообщение читайте как подсказку.
Если в таблице встречаются два формата, пробуйте их по очереди: первый не подошёл — во except пробуем второй.
from datetime import datetime
def parse(s):
for fmt in ("%d.%m.%Y", "%Y-%m-%d"):
try:
return datetime.strptime(s, fmt).date()
except ValueError:
pass
raise ValueError("Не понимаю дату: " + s)
print(parse("29.09.2026"))
print(parse("2026-09-30"))
2026-09-29
2026-09-30
Проверьте себя
Задание. Программа считает строки, в которых дата разобралась. Что она выведет? Введите число.
Исходный код для этого задания:
from datetime import datetime dates = ["29.09.2026", "31.09.2026", "2026-09-30", "01.10.2026", "30.02.2026", "15.10.2026"] ok = 0 for s in dates: try: datetime.strptime(s, "%d.%m.%Y") ok += 1 except ValueError: pass print(ok)Подсказка: Проверьте каждую строку два раза: подходит ли под шаблон «день.месяц.год» и существует ли такой день в календаре.
✅ Готово, если: программа запускается без ошибок и выводит то, что просят в задании.
Онлайн-проверка ответа появится позже
Сквозная задача: расходы по месяцам
Соберём всё вместе. Таблица расходов, как в главе 1, но за два месяца и с датами полностью. Ключ группировки — strftime("%Y-%m"), а суммы складываем в словарь уже знакомым приёмом totals.get(key, 0).
from datetime import datetime
rows = [
("29.09.2026", "Еда", 450),
("30.09.2026", "Такси", 380),
("31.09.2026", "Еда", 999), # такой даты нет
("01.10.2026", "Связь", 300),
("03.10.2026", "Еда", 620),
]
totals = {}
for s, cat, amount in rows:
try:
d = datetime.strptime(s, "%d.%m.%Y")
except ValueError:
print("Пропускаю строку с датой", s)
continue
month = d.strftime("%Y-%m")
totals[month] = totals.get(month, 0) + amount
for month in sorted(totals):
print(month, totals[month])
Пропускаю строку с датой 31.09.2026
2026-09 830
2026-10 920

Тот же приём с параметром key, что с max в главе 1, сортирует строки по настоящей дате, а не по тексту:
from datetime import datetime
def as_date(s):
return datetime.strptime(s, "%d.%m.%Y")
dates = ["01.10.2026", "29.09.2026", "05.09.2026"]
print(sorted(dates))
print(sorted(dates, key=as_date))
['01.10.2026', '05.09.2026', '29.09.2026']
['05.09.2026', '29.09.2026', '01.10.2026']
В key передают имя функции без скобок. sorted сам вызывает as_date для каждой строки и сравнивает результаты — даты, а не текст. Сами строки в списке не меняются.
Проверьте себя
Задание. Программа ищет самый поздний платёж в списке. Что она выведет? Введите дату ровно так, как её напечатает print.
Исходный код для этого задания:
from datetime import datetime def as_date(s): return datetime.strptime(s, "%d.%m.%Y") dates = ["03.10.2026", "28.09.2026", "15.09.2026", "01.10.2026"] print(sorted(dates, key=as_date)[-1])Подсказка: sorted сравнивает не сами строки, а то, что вернула as_date. Последний элемент отсортированного списка — наибольший.
✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.
Онлайн-проверка ответа появится позже
Задание. Программа ищет месяц с наибольшими расходами. Что она выведет? Введите строку ровно так, как её напечатает print.
Исходный код для этого задания:
from datetime import datetime rows = [("28.08.2026", 1200), ("30.09.2026", 700), ("02.09.2026", 650), ("31.08.2026", 100), ("01.10.2026", 900), ("15.10.2026", 350), ("10.09.2026", 200)] totals = {} for s, amount in rows: month = datetime.strptime(s, "%d.%m.%Y").strftime("%Y-%m") totals[month] = totals.get(month, 0) + amount print(max(totals, key=totals.get))Подсказка: Разложите строки по ключам «ГГГГ-ММ», сложите суммы в каждом и сравните итоги.
✅ Готово, если: программа запускается без ошибок и выводит то, что просят в задании.
Онлайн-проверка ответа появится позже
Задание. Проектная миссия «Горящие сроки». Напишите утилиту для файла srok.csv (UTF-8, разделитель ;, первая строка — заголовок, данные целиком ниже, 52 строки). Даты сроков записаны в двух форматах: «ДД.ММ.ГГГГ» и «ГГГГ-ММ-ДД». Сегодня зафиксировано: 30.09.2026 — задайте его в программе как date(2026, 9, 30), не через today(). Программа печатает по каждому делу, сколько дней осталось, а в конце — сколько дел нужно закрыть в ближайшие две недели: от 0 до 14 дней включительно (просроченные не считаются). Приложите файл программы .py; в поле ответа — число.
Принято, если:
1. введённое число совпадает с эталоном;
2. приложен файл .py, который это число выдаёт на данных из условия.Самопроверка перед сдачей (преподаватель смотрит на занятии):
3. оба формата даты разбираются одной функцией, второй формат пробуется в except ValueError;
4. «сегодня» задано одной переменной — поменяли её, и программа пересчитала всё.дело;срок
Кредит 1;2026-09-22
Техосмотр 2;28.09.2026
Телефон 3;2026-09-15
Подписка 4;15.10.2026
Взнос 5;14.11.2026
Интернет 6;11.09.2026
Кружок 7;08.10.2026
Телефон 8;28.09.2026
Врач 9;16.10.2026
Паспорт 10;28.09.2026
Врач 11;2026-11-09
ОСАГО 12;28.09.2026
Взнос 13;12.11.2026
Взнос 14;07.10.2026
Подписка 15;25.10.2026
Отчёт 16;14.10.2026
Взнос 17;2026-09-08
Аренда 18;11.11.2026
Взнос 19;31.10.2026
Кружок 20;2026-10-26
Интернет 21;2026-11-09
Кружок 22;17.09.2026
Отчёт 23;2026-09-26
Техосмотр 24;2026-10-19
Аренда 25;29.09.2026
Кружок 26;2026-11-12
Взнос 27;2026-09-17
Кредит 28;20.09.2026
Коммуналка 29;10.09.2026
Паспорт 30;2026-11-11
Аренда 31;04.11.2026
Налог 32;20.10.2026
Интернет 33;08.10.2026
Аренда 34;28.09.2026
Взнос 35;2026-10-18
Аренда 36;2026-10-09
Налог 37;29.09.2026
Коммуналка 38;02.10.2026
Врач 39;2026-09-13
Кружок 40;17.09.2026
Подписка 41;26.10.2026
Телефон 42;2026-09-09
Коммуналка 43;2026-10-01
Взнос 44;2026-10-23
Абонемент 45;2026-11-03
Аренда 46;2026-09-19
ОСАГО 47;2026-09-25
Подписка 48;2026-09-12
Коммуналка 49;2026-10-10
Интернет 50;2026-09-08
Кредит 51;02.10.2026
Взнос 52;04.10.2026
Подсказка: Функция parse(s) из урока пробует форматы по очереди. Дальше (срок − сегодня).days и условие с двумя границами.
✅ Готово, если: ответ раскрывает то, что просит критерий приёмки в задании выше.
Онлайн-проверка ответа появится позже
Задание. Проектная миссия «Расходы по месяцам». Напишите утилиту для файла rashody.csv (кодировка utf-8-sig, разделитель ;, первая строка — заголовок, данные целиком ниже, 56 строк за июль–сентябрь). Таблицу заполняли руками, и в нескольких строках дата кривая: несуществующий день или не тот формат. Такие строки программа пропускает и сообщает о каждой, но не падает. Остальное складывает по месяцам (ключ «ГГГГ-ММ») и печатает итоги в порядке месяцев. В поле ответа — сумма расходов самого дорогого месяца. Приложите файл программы .py; в поле ответа — число.
Принято, если:
1. введённое число совпадает с эталоном;
2. приложен файл .py, который это число выдаёт на данных из условия.Самопроверка перед сдачей (преподаватель смотрит на занятии):
3. строки с плохой датой перечислены в выводе, программа дошла до конца;
4. месяцы напечатаны по порядку, а не как попало.дата;статья;сумма
18.07.2026;Связь;1200
03.08.2026;Подарки;2750
27.09.2026;Еда;2350
18.08.2026;Аптека;2150
14.07.2026;Такси;2850
18.09.2026;Аптека;2200
16.08.2026;Связь;2850
31.09.2026;Подарки;1750
03.08.2026;Такси;950
05.08.2026;Аптека;650
14.08.2026;Подарки;2650
04.09.2026;Кино;2350
02.09.2026;Подарки;550
07.09.2026;Такси;1700
21.08.2026;Связь;2900
10.07.2026;Кино;2250
22.09.2026;Аптека;750
29.09.2026;Такси;400
07.07.2026;Кино;1200
30.02.2026;Такси;300
05.09.2026;Аптека;2850
20.07.2026;Такси;1900
16.08.2026;Подарки;2050
01.07.2026;Аптека;1150
03.07.2026;Еда;1750
26.09.2026;Еда;2700
19.09.2026;Подарки;350
13.07.2026;Аптека;350
23.07.2026;Связь;1750
08.08.2026;Связь;1450
12.09.2026;Аптека;1800
09.09.2026;Связь;1150
25.09.2026;Подарки;2450
2026.10.05;Еда;3000
30.07.2026;Подарки;1750
22.09.2026;Связь;2300
06.08.2026;Еда;900
01.08.2026;Еда;500
10.08.2026;Связь;2950
04.07.2026;Связь;500
14.07.2026;Кино;2750
12.08.2026;Такси;650
31.08.2026;Связь;1450
20.08.2026;Связь;550
15.13.2026;Подарки;1400
09.08.2026;Такси;1850
30.07.2026;Аптека;1300
06.07.2026;Кино;1000
04.09.2026;Аптека;800
12.07.2026;Такси;2750
31.07.2026;Подарки;1100
10.09.2026;Такси;1550
07.07.2026;Связь;900
20.07.2026;Еда;1900
31.08.2026;Связь;2700
22.07.2026;Аптека;1350
Подсказка: Чтение — csv.DictReader из главы 1, дата — strptime внутри try, ключ — strftime(«%Y-%m»), сумма — словарь с get(key, 0). В конце — наибольшее из значений словаря.
✅ Готово, если: ответ раскрывает то, что просит критерий приёмки в задании выше.
Онлайн-проверка ответа появится позже
Что дальше
Теперь вы умеете превращать строку с датой в объект через strptime, считать дни до срока разностью дат, прибавлять к дате timedelta, печатать дату в нужном виде через strftime, группировать расходы по месяцам и пропускать строки с кривой датой. В следующем уроке научимся вытаскивать из текста то, что спрятано внутри строк: телефоны, почты и суммы — регулярными выражениями.
← Назад · ↑ В начало урока · ⌂ К навигатору курса · Вперёд →
