Модуль calendar. Основные функции, классы и методы

Курс по стандартной библиотеке: https://stepik.org/a/259466?utm_source=proproprogs

Смотреть материал на YouTube | RuTube

На предыдущих занятиях мы с вами рассмотрели три класса работы с датой и временем: time, date и datetime модуля datetime, которые чаще всего применяются на практике. Но есть еще один модуль calendar, позволяющий оперировать календарем в целом и соответствующими календарными датами. В ряде задач это бывает весьма полезно.

https://docs.python.org/3/library/calendar.html

Чтобы воспользоваться календарем, достаточно импортировать модуль calendar:

import 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() выводит в консоль календарь за весь указанный год, например:

calendar.prcal(2025)

Или то же самое, но с выводом в строку:

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. Например:

my_cal.prmonth(2025, 7)

выведет 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

Видео по теме