Рубрики
Без рубрики

календарь – Работа с датами

Автор оригинала: Doug Hellmann.

Цель:

В модуле календаря реализованы классы для работы с даты для управления значениями, ориентированными на год/месяц/неделю.

Модуль calendar определяет класс Calendar , который инкапсулирует вычисления для таких значений, как даты недель в данном месяце или году. Кроме того, классы TextCalendar и HTMLCalendar могут создавать предварительно отформатированный вывод.

Примеры форматирования

Метод prmonth () – это простая функция, которая выводит форматированный текст в течение месяца.

calendar_textcalendar.py

import calendar

c  calendar.TextCalendar(calendar.SUNDAY)
c.prmonth(2017, 7)

В этом примере TextCalendar настраивается так, чтобы недели начинались в воскресенье, в соответствии с американским соглашением. По умолчанию используется европейское соглашение о начале недели с понедельника.

Результат выглядит так:

$ python3 calendar_textcalendar.py

     July 2017
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

Аналогичную таблицу HTML можно создать с помощью HTMLCalendar и formatmonth () . Отрендеренный вывод выглядит примерно так же, как и версия с обычным текстом, но заключен в HTML-теги. Каждая ячейка таблицы имеет атрибут класса, соответствующий дню недели, поэтому HTML можно стилизовать с помощью CSS.

Чтобы получить вывод в формате, отличном от одного из доступных по умолчанию, используйте calendar для вычисления дат и организации значений в диапазоны недель и месяцев, а затем переберите результат. Для этого особенно полезны методы weekheader () , monthcalendar () и yeardays2calendar () в Calendar .

Вызов yeardays2calendar () создает последовательность списков «строки месяца». Каждый список включает месяцы как другой список недель. Недели – это списки кортежей, состоящие из номера дня (1-31) и номера дня недели (0-6). Дни, выходящие за пределы месяца, имеют номер дня 0.

calendar_yeardays2calendar.py

import calendar
import pprint

cal  calendar.Calendar(calendar.SUNDAY)

cal_data  cal.yeardays2calendar(2017, 3)
print('len(cal_data)      :', len(cal_data))

top_months  cal_data[0]
print('len(top_months)    :', len(top_months))

first_month  top_months[0]
print('len(first_month)   :', len(first_month))

print('first_month:')
pprint.pprint(first_month, width65)

Вызов yeardays2calendar (2017, 3) возвращает данные за 2017 год, сгруппированные по три месяца в строке.

$ python3 calendar_yeardays2calendar.py

len(cal_data)      : 4
len(top_months)    : 3
len(first_month)   : 5
first_month:
[[(1, 6), (2, 0), (3, 1), (4, 2), (5, 3), (6, 4), (7, 5)],
 [(8, 6), (9, 0), (10, 1), (11, 2), (12, 3), (13, 4), (14, 5)],
 [(15, 6), (16, 0), (17, 1), (18, 2), (19, 3), (20, 4), (21,
5)],
 [(22, 6), (23, 0), (24, 1), (25, 2), (26, 3), (27, 4), (28,
5)],
 [(29, 6), (30, 0), (31, 1), (0, 2), (0, 3), (0, 4), (0, 5)]]

Это эквивалентно данным, используемым formatyear () .

calendar_formatyear.py

import calendar

cal  calendar.TextCalendar(calendar.SUNDAY)
print(cal.formatyear(2017, 2, 1, 1, 3))

Для тех же аргументов formatyear () производит следующий вывод:

$ python3 calendar_formatyear.py

                              2017

      January               February               March
Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa
 1  2  3  4  5  6  7            1  2  3  4            1  2  3  4
 8  9 10 11 12 13 14   5  6  7  8  9 10 11   5  6  7  8  9 10 11
15 16 17 18 19 20 21  12 13 14 15 16 17 18  12 13 14 15 16 17 18
22 23 24 25 26 27 28  19 20 21 22 23 24 25  19 20 21 22 23 24 25
29 30 31              26 27 28              26 27 28 29 30 31

       April                  May                   June
Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa
                   1      1  2  3  4  5  6               1  2  3
 2  3  4  5  6  7  8   7  8  9 10 11 12 13   4  5  6  7  8  9 10
 9 10 11 12 13 14 15  14 15 16 17 18 19 20  11 12 13 14 15 16 17
16 17 18 19 20 21 22  21 22 23 24 25 26 27  18 19 20 21 22 23 24
23 24 25 26 27 28 29  28 29 30 31           25 26 27 28 29 30
30

        July                 August              September
Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa
                   1         1  2  3  4  5                  1  2
 2  3  4  5  6  7  8   6  7  8  9 10 11 12   3  4  5  6  7  8  9
 9 10 11 12 13 14 15  13 14 15 16 17 18 19  10 11 12 13 14 15 16
16 17 18 19 20 21 22  20 21 22 23 24 25 26  17 18 19 20 21 22 23
23 24 25 26 27 28 29  27 28 29 30 31        24 25 26 27 28 29 30
30 31

      October               November              December
Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa
 1  2  3  4  5  6  7            1  2  3  4                  1  2
 8  9 10 11 12 13 14   5  6  7  8  9 10 11   3  4  5  6  7  8  9
15 16 17 18 19 20 21  12 13 14 15 16 17 18  10 11 12 13 14 15 16
22 23 24 25 26 27 28  19 20 21 22 23 24 25  17 18 19 20 21 22 23
29 30 31              26 27 28 29 30        24 25 26 27 28 29 30
                                            31

Атрибуты модуля day_name , day_abbr , month_name и month_abbr полезны для создания вывода в настраиваемом формате (т. Е. Для включения ссылки в выводе HTML). Они автоматически правильно настроены для текущей локали.

Locales

Чтобы создать календарь, отформатированный для языкового стандарта, отличного от текущего по умолчанию, используйте LocaleTextCalendar или LocaleHTMLCalendar .

calendar_locale.py

import calendar

c  calendar.LocaleTextCalendar(locale'en_US')
c.prmonth(2017, 7)

print()

c  calendar.LocaleTextCalendar(locale'fr_FR')
c.prmonth(2017, 7)

Первый день недели не является частью настроек локали, и значение берется из аргумента класса календаря, как и для обычного TextCalendar .

$ python3 calendar_locale.py

     July 2017
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

    juillet 2017
Lu Ma Me Je Ve Sa Di
                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

Расчет дат

Хотя модуль календаря в основном ориентирован на печать полных календарей в различных форматах, он также предоставляет функции, полезные для работы с датами другими способами, например, для расчета дат для повторяющегося события. Например, группа пользователей Python в Атланте встречается во второй четверг каждого месяца. Чтобы рассчитать даты собраний на год, используйте возвращаемое значение monthcalendar () .

calendar_monthcalendar.py

import calendar
import pprint

pprint.pprint(calendar.monthcalendar(2017, 7))

Некоторые дни имеют значение 0. Это дни недели, которые совпадают с данным месяцем, но являются частью другого месяца.

$ python3 calendar_monthcalendar.py

[[0, 0, 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, 0, 0, 0, 0, 0]]

По умолчанию первый день недели – понедельник. Это можно изменить, вызвав setfirstweekday () , но поскольку модуль календаря включает константы для индексации в диапазонах дат, возвращаемых monthcalendar () , удобнее пропустите этот шаг в этом случае.

Чтобы рассчитать даты групповых встреч на год, предполагая, что они всегда приходятся на второй четверг каждого месяца, просмотрите выходные данные monthcalendar () , чтобы найти даты, на которые приходятся четверги. Первая и последняя неделя месяца дополняются 0 значениями в качестве заполнителей для дней, приходящихся на предыдущий или последующий месяц. Например, если месяц начинается в пятницу, значение первой недели в позиции четверга будет равно 0.

calendar_secondthursday.py

import calendar
import sys

year  int(sys.argv[1])

# Show every month
for month in range(1, 13):

    # Compute the dates for each week that overlaps the month
    c  calendar.monthcalendar(year, month)
    first_week  c[0]
    second_week  c[1]
    third_week  c[2]

    # If there is a Thursday in the first week,
    # the second Thursday is # in the second week.
    # Otherwise, the second Thursday must be in
    # the third week.
    if first_week[calendar.THURSDAY]:
        meeting_date  second_week[calendar.THURSDAY]
    else:
        meeting_date  third_week[calendar.THURSDAY]

    print('{:>3}: {:>2}'.format(calendar.month_abbr[month],
                                meeting_date))

Итак, расписание встреч на год:

$ python3 calendar_secondthursday.py 2017

Jan: 12
Feb:  9
Mar:  9
Apr: 13
May: 11
Jun:  8
Jul: 13
Aug: 10
Sep: 14
Oct: 12
Nov:  9
Dec: 14

Смотрите также