Курс по стандартной библиотеке: https://stepik.org/a/259466?utm_source=proproprogs
На предыдущих
занятиях мы с вами рассмотрели три класса работы с датой и временем: time, date и datetime модуля datetime, которые чаще
всего применяются на практике. Но есть еще один модуль calendar, позволяющий
оперировать календарем в целом и соответствующими календарными датами. В ряде
задач это бывает весьма полезно.
https://docs.python.org/3/library/calendar.html
Чтобы
воспользоваться календарем, достаточно импортировать модуль calendar:
И первым делом
воспользуемся функциями для красивого форматированного вывода календарных дат.
В самом простом варианте можно вызвать функцию:
calendar.prmonth(2025, 7)
которая печатает
в консоли 7-й календарный месяц 2025-го года:
July 2025
Mo Tu We Th Fr Sa Su
1 2 3 4 5 6
7
8 9 10 11 12 13
14
15 16 17 18 19 20
21
22 23 24 25 26 27
28 29 30 31
Обратите
внимание, что первый день недели по умолчанию понедельник с порядковым номером
0. При желании это можно изменить, используя функцию setfirstweekday():
calendar.setfirstweekday(calendar.SUNDAY)
calendar.prmonth(2025, 7)
Теперь недели
месяца отображаются с воскресенья.
В функции setfirstweekday()
использовалась константа calendar.SUNDAY. Это предопределенные значения,
прописанные в модуле calendar для дней недели. Они следующие (нумерация с 0 до
6):
- calendar.MONDAY
- calendar.TUESDAY
- calendar.WEDNESDAY
- calendar.THURSDAY
- calendar.FRIDAY
- calendar.SATURDAY
- calendar.SUNDAY
И также в Python версии 3.12 были
добавлены значения для названий месяцев (нумерация от 1 до 12):
- calendar.JANUARY
- calendar.FEBRUARY
- calendar.MARCH
- calendar.APRIL
- calendar.MAY
- calendar.JUNE
- calendar.JULY
- calendar.AUGUST
- calendar.SEPTEMBER
- calendar.OCTOBER
- calendar.NOVEMBER
- calendar.DECEMBER
Для определения
первого установленного дня недели календаря можно выполнить функцию firstweekday():
wday = calendar.firstweekday() # 6
Если же
календарь нужно сформировать в виде строки, а не для вывода в консоль, то можно
воспользоваться функцией:
s_july = calendar.month(2025, 7)
Получим
аналогичный календарь для месяца июля, но представленного в строке s_july.
Следующая
функция prcal() выводит в консоль календарь за весь указанный год, например:
Или то же самое,
но с выводом в строку:
s_year = calendar.calendar(2025)
На самом деле,
если посмотреть на способ реализации представленных функций модуля calendar, то увидим
такую запись (в модуле calendar):
c = TextCalendar()
firstweekday = c.getfirstweekday
То есть функции
на самом деле являются соответствующими методами объекта c класса TextCalendar.
В действительности, мы можем в программе самостоятельно создавать объекты этого
класса, формируя, таким образом, свои независимые календари. Например:
my_cal = calendar.TextCalendar(firstweekday=calendar.SUNDAY)
Инициализатор класса
TextCalendar имеет параметр firstweekday, определяющий
первый день недели. По умолчанию используется понедельник. Мы же создали свой
собственный календарь my_cal, где недели
начинаются с воскресенья.
Далее этим
календарем можно пользоваться так же, как и стандартным из модуля calendar. Например:
выведет 7-й месяц
2025-го года, начиная недели с воскресенья:
July 2025
Su Mo Tu We Th Fr Sa
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28
29 30 31
Или то же самое,
но с выводом в строку:
s = my_cal.formatmonth(2025, 7)
Аналогичный
функционал предоставляет еще один класс HTMLCalendar, который формирует вывод с
HTML-разметкой.
Например:
html_cal = calendar.HTMLCalendar()
html_output = html_cal.formatmonth(2023, 7)
Вообще, чтобы
понять, какие методы классов TextCalendar или HTMLCalendar
соответствуют функциям модуля calendar, достаточно перейти по ним и
увидеть прописанные (в модуле calendar) взаимосвязи:
monthcalendar = c.monthdayscalendar
prweek = c.prweek
week = c.formatweek
weekheader = c.formatweekheader
prmonth = c.prmonth
month = c.formatmonth
calendar = c.formatyear
prcal = c.pryear
Некоторые
названия совпадают, но не все. Однако функционал у них идентичен. Поэтому
вернемся к рассмотрению основных функций модуля calendar.
Простое
отображение календарей в консоли или на уровне HTML-разметки – это,
на мой взгляд, не главное достоинство модуля calendar. У него есть
набор функций, возвращающие дни недели, которые позволяют достаточно просто
выполнять планирование событий по конкретным датам. Для этого непосредственно
модуль calendar содержит две
функции:
- monthrange(year, month) – возвращает кортеж
в формате: (первый день недели, число дней в месяце);
- monthcalendar(year, month) – возвращает список
с распределением дней по неделям в рамках указанного месяца.
Например:
calendar.monthrange(2025, 5) # (3, 31)
так как первый
день недели мая 2025-го года – это четверг (3-й порядковый номер, начиная с
0-го понедельника), а всего дней в месяце – 31.
А функция:
days_of_weeks = calendar.monthcalendar(2025, 5)
вернет следующий
список:
[[0,
0, 0, 1, 2, 3, 4],
[5,
6, 7, 8, 9, 10, 11],
[12,
13, 14, 15, 16, 17, 18],
[19,
20, 21, 22, 23, 24, 25],
[26, 27, 28,
29, 30, 31, 0]]
Нули означают
дни других месяцев (предыдущего и последующего), а номера – порядковые номера
дней месяца.
Класс Calendar
Помимо этих двух
функций модуль calendar позволяет создавать объекты класса Calendar,
предоставляющий дополнительные возможности.
Объекты этого
класса создаются командой:
cal = calendar.Calendar()
или так:
cal_sun = calendar.Calendar(calendar.SUNDAY)
Во втором случае
мы поменяли первый день недели с понедельника на воскресенье.
Объекты этого
класса имеют следующие методы:
|
Функция
|
Описание
|
|
iterweekdays()
|
возвращает
итератор для перебора номеров дней недели
|
|
itermonthdates(year,
month)
|
возвращает
итератор для перебора дней месяца в виде объектов класса date
|
|
itermonthdays(year,
month)
|
возвращает
итератор для перебора дней месяца по их порядковым номерам
|
|
itermonthdays2(year,
month)
|
возвращает
итератор для перебора кортежей в формате:
(день
месяца, день недели)
|
|
itermonthdays3(year,
month)
|
возвращает
итератор для перебора кортежей в формате:
(год,
месяц, день)
|
|
itermonthdays4(year,
month)
|
возвращает
итератор для перебора кортежей в формате:
(год,
месяц, день месяца, день недели)
|
|
monthdatescalendar(year,
month)
|
возвращает
список по неделям с днями месяца в виде объектов класса date
|
|
monthdayscalendar(year,
month)
|
возвращает
список по неделям из номеров дней месяца (0 – дни других месяцев)
|
|
monthdays2calendar(year,
month)
|
возвращает
список кортежей по неделям в формате:
(день
месяца, день недели)
|
|
yeardatescalendar(year,
width=3)
|
возвращает
в виде вложенных списков даты по дням в течение года в виде объектов класса date
|
|
yeardayscalendar(year,
width=3)
|
возвращает
в виде вложенных списков месяцы указанного года с порядковыми номерами дней
месяцев
|
|
yeardays2calendar(year,
width=3)
|
возвращает
в виде вложенных списков месяцы указанного года в виде кортежей:
(номер
месяца, номер недели)
|
Пользоваться
всеми этими методами очень просто. Например, первый iterweekdays() даст
следующие результаты для объектов cal и cal_sun:
it = cal.iterweekdays()
it_sun = cal_sun.iterweekdays()
list(it) # [0, 1, 2, 3, 4, 5, 6]
list(it_sun) # [6, 0, 1, 2, 3, 4, 5]
Вначале мы
получили итераторы it и it_sun, а затем
перебрали их для построения списков.
Так же
используются и все остальные итераторы, например:
list(cal.itermonthdates(2025, 7))
результат:
[datetime.date(2025,
6, 30), datetime.date(2025, 7, 1), datetime.date(2025, 7, 2),
datetime.date(2025, 7, 3), datetime.date(2025, 7, 4), datetime.date(2025, 7,
5), datetime.date(2025, 7, 6), datetime.date(2025, 7, 7), datetime.date(2025,
7, 8), datetime.date(2025, 7, 9), datetime.date(2025, 7, 10),
datetime.date(2025, 7, 11), datetime.date(2025, 7, 12), datetime.date(2025, 7,
13), datetime.date(2025, 7, 14), datetime.date(2025, 7, 15),
datetime.date(2025, 7, 16), datetime.date(2025, 7, 17), datetime.date(2025, 7,
18), datetime.date(2025, 7, 19), datetime.date(2025, 7, 20),
datetime.date(2025, 7, 21), datetime.date(2025, 7, 22), datetime.date(2025, 7,
23), datetime.date(2025, 7, 24), datetime.date(2025, 7, 25),
datetime.date(2025, 7, 26), datetime.date(2025, 7, 27), datetime.date(2025, 7,
28), datetime.date(2025, 7, 29), datetime.date(2025, 7, 30), datetime.date(2025,
7, 31), datetime.date(2025, 8, 1), datetime.date(2025, 8, 2),
datetime.date(2025, 8, 3)]
Команда:
list(cal.itermonthdays2(2025, 7))
результат:
[(0, 0), (1, 1),
(2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 0), (8, 1), (9, 2), (10, 3), (11,
4), (12, 5), (13, 6), (14, 0), (15, 1), (16, 2), (17, 3), (18, 4), (19, 5),
(20, 6), (21, 0), (22, 1), (23, 2), (24, 3), (25, 4), (26, 5), (27, 6), (28,
0), (29, 1), (30, 2), (31, 3), (0, 4), (0, 5), (0, 6)]
И так для всех
остальных подобных методов. Остальные шесть функций сразу выдают список с
соответствующей информацией по датам. Например:
cal.monthdatescalendar(2025, 7)
результат:
[[datetime.date(2025,
6, 30), datetime.date(2025, 7, 1), datetime.date(2025, 7, 2),
datetime.date(2025, 7, 3), datetime.date(2025, 7, 4), datetime.date(2025, 7,
5), datetime.date(2025, 7, 6)], [datetime.date(2025, 7, 7), datetime.date(2025,
7, 8), datetime.date(2025, 7, 9), datetime.date(2025, 7, 10),
datetime.date(2025, 7, 11), datetime.date(2025, 7, 12), datetime.date(2025, 7,
13)], [datetime.date(2025, 7, 14), datetime.date(2025, 7, 15),
datetime.date(2025, 7, 16), datetime.date(2025, 7, 17), datetime.date(2025, 7,
18), datetime.date(2025, 7, 19), datetime.date(2025, 7, 20)],
[datetime.date(2025, 7, 21), datetime.date(2025, 7, 22), datetime.date(2025, 7,
23), datetime.date(2025, 7, 24), datetime.date(2025, 7, 25),
datetime.date(2025, 7, 26), datetime.date(2025, 7, 27)], [datetime.date(2025,
7, 28), datetime.date(2025, 7, 29), datetime.date(2025, 7, 30),
datetime.date(2025, 7, 31), datetime.date(2025, 8, 1), datetime.date(2025, 8,
2), datetime.date(2025, 8, 3)]]
Команда:
cal.monthdays2calendar(2025, 7)
результат:
[[(0, 0), (1,
1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)], [(7, 0), (8, 1), (9, 2), (10, 3),
(11, 4), (12, 5), (13, 6)], [(14, 0), (15, 1), (16, 2), (17, 3), (18, 4), (19,
5), (20, 6)], [(21, 0), (22, 1), (23, 2), (24, 3), (25, 4), (26, 5), (27, 6)],
[(28, 0), (29, 1), (30, 2), (31, 3), (0, 4), (0, 5), (0, 6)]]
Далее, эти
данные очевидным образом можно использовать для планирования произвольных
событий в своих программах.
Курс по стандартной библиотеке: https://stepik.org/a/259466?utm_source=proproprogs