2021-03-30に更新

Python 標準ライブラリ calendar カレンダー

読了目安:11分

Pythonの標準にあるカレンダーを取り扱うためのライブラリcalendarの解説です。

概要

calendarモジュールにはカレンダー出力を行うためのクラス・関数が用意されています。

Calendarクラスは年・月について週や日の繰り返し処理やリストの操作機能を持っています。

Calendarを継承したTextCalendarやHTMLCalendarでは、
プレーンなテキストやHTML文字列でカレンダーの出力を行います。
LocaleTextCalendar、LocaleHTMLCalendarはTextCalendarやHTMLCalendarのロケール対応版です。

Calendar カレンダーの基底クラス

from calendar import Calendar

# Calendar(firstweekday=0) 週の始まりを指定(0月曜~6日曜)
cal = Calendar()

# iterweekdays() 曜日の数字1週間分
list(cal.iterweekdays()) # => [0, 1, 2, 3, 4, 5, 6]

# itermonthdates(year, month) 指定月度のdatetime.dateのイテレータ(週の欠けを埋める)
list(cal.itermonthdates(2021, 4)) 
# => [ 
# datetime.date(2021, 3, 29),
# datetime.date(2021, 3, 30),
# datetime.date(2021, 3, 31),
# datetime.date(2021, 4, 1),
# …
# datetime.date(2021, 4, 30),
# datetime.date(2021, 5, 1),
# datetime.date(2021, 5, 2)
# ]

# itermonthdays(year, month) 指定月度の日にちのイテレータ(週の欠けを埋める)
list(cal.itermonthdays(2021, 4)) # => [datetime.date(2021, 3, 29),…,datetime.date(2021, 5, 2)]
# => [
# 0,
# 0,
# 0,
# 1,
# …
# 30,
# 0,
# 0
# ]

# itermonthdays2(year, month) 指定月度の日・曜日のタプルのイテレータ(週の欠けを埋める)
list(cal.itermonthdays2(2021, 4))
# => [
#  (0, 0),
#  (0, 1),
#  (0, 2),
#  (1, 3),
#  …
#  (30, 4),
#  (0, 5),
#  (0, 6)
# ]

# itermonthdays3(year, month) 指定月度の年・月・日のタプルのイテレータ(週の欠けを埋める)
list(cal.itermonthdays3(2021, 4))
# => [
# (2021, 3, 29), 
# (2021, 3, 30), 
# (2021, 3, 31), 
# (2021, 4, 1), 
#  …
# (2021, 4, 30), 
# (2021, 5, 1), 
# (2021, 5, 2)
# ]

# itermonthdays4(year, month) 指定月度の年・月・日・曜日のタプルのイテレータ(週の欠けを埋める)
list(cal.itermonthdays4(2021, 4))
# => [
# (2021, 3, 29, 0), 
# (2021, 3, 30, 1), 
# (2021, 3, 31, 2), 
# (2021, 4, 1, 3), 
#  …
# (2021, 4, 30, 4), 
# (2021, 5, 1, 5), 
# (2021, 5, 2, 6)
# ]

# monthdatescalendar(year, month) 指定月度の週毎のdatetime.dateのリスト(週の欠けを埋める)
cal.monthdatescalendar(2021, 4)
# => [
# [datetime.date(2021, 3, 29), …, datetime.date(2021, 4, 4)],
# [datetime.date(2021, 4, 5),  …, datetime.date(2021, 4, 11)],
# [datetime.date(2021, 4, 12), …, datetime.date(2021, 4, 18)],
# [datetime.date(2021, 4, 19), …, datetime.date(2021, 4, 25)],
# [datetime.date(2021, 4, 26), …, datetime.date(2021, 5, 2)]
# ]


# monthdays2calendar(year, month) 指定月度の週毎の日・曜日のリスト(週の欠けを埋める)
cal.monthdays2calendar(2021, 4)
# => [
# [(0, 0), (0, 1), (0, 2), (1, 3), (2, 4), (3, 5), (4, 6)],
# [(5, 0), (6, 1), (7, 2), (8, 3), (9, 4), (10, 5), (11, 6)],
# [(12, 0), (13, 1), (14, 2), (15, 3), (16, 4), (17, 5), (18, 6)],
# [(19, 0), (20, 1), (21, 2), (22, 3), (23, 4), (24, 5), (25, 6)],
# [(26, 0), (27, 1), (28, 2), (29, 3), (30, 4), (0, 5), (0, 6)]
# ]

# monthdayscalendar(year, month) 指定月度の週毎の日のリスト(週の欠けを埋める)
cal.monthdayscalendar(2021, 4)
# =>周舞
# [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, 0, 0]
# ]

# yeardatescalendar(year, width=3) 指定年の週毎・月毎のdatetime.dateのリスト
cal.yeardatescalendar(2021)

# yeardays2calendar(year, width=3) 指定年の週毎・月毎の日・曜日のリスト
cal.yeardays2calendar(2021)

# yeardayscalendar(year, width=3) 指定年の週毎・月毎の日のリスト
cal.yeardayscalendar(2021)

TextCalendar プレーンテキストでのカレンダー出力

from calendar import TextCalendar
text_cal = TextCalendar()

# formatmonth(theyear, themonth, w=0, l=0) 1月分のカレンダーの文字列 w:日の列幅、l:週の高さ
print(text_cal.formatmonth(2021, 4))
# => 
"""
     April 2021
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
"""

# prmonth(theyear, themonth, w=0, l=0) formatmonthを出力
text_cal.prmonth(2021, 4)
# => 
"""
     April 2021
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
"""

# formatyear(theyear, w=2, l=1, c=6, m=3) 指定年のカレンダーの文字列  w:日の列幅、l:週の高さ、c:月の間隔、m:月の横繰り返し数
print(text_cal.formatyear(2021))

# formatyear(theyear, w=2, l=1, c=6, m=3) 指定年のカレンダーを出力  w:日の列幅、l:週の高さ、c:月の間隔、m:月の横繰り返し数
text_cal.pryear(2021)

HTMLCalendar HTMLでのカレンダー出力

from calendar import HTMLCalendar

html_cal = HTMLCalendar()

# formatmonth(theyear, themonth, withyear=True) 指定月度のカレンダをHTMLテーブルで取得 withyear:ヘッダに年を含むか
print(html_cal.formatmonth(2021, 4))

# formatyear(theyear, width=3) 指定年のカレンダをHTMLテーブルで取得 width:横に表示する月数
print(html_cal.formatyear(2021))

# formatyearpage(theyear, width=3, css='calendar.css', encoding=None) 指定年のカレンダーの完全なHTMLページ
print(html_cal.formatyearpage(2021))

## HTMLの各タグに設定されているCSSスタイルは以下で参照・設定できる
# 各曜日のCSSスタイル
html_cal.cssclasses # => ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']
# 前後月のCSSスタイル
html_cal.cssclass_noday # => 'noday'
# 曜日ヘッダのCSSスタイル
html_cal.cssclasses_weekday_head # => ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']
# 月ヘッダのCSSスタイル
html_cal.cssclass_month_head # => 'month'
# 月テーブルのCSSスタイル
html_cal.cssclass_month # => 'month'
# 年テーブルのCSSスタイル
html_cal.cssclass_year # => 'year'
# 年ヘッダのCSSスタイル
html_cal.cssclass_year_head # => 'year'

以下はカレンダーの出力例です。

April 2021
MonTueWedThuFriSatSun
   1234
567891011
12131415161718
19202122232425
2627282930  

LocaleTextCalendar ロケール対応のプレーンテキストでのカレンダー出力

from calendar import LocaleTextCalendar

l_text_cal = LocaleTextCalendar(locale='ja_JP')
l_text_cal.prmonth(2021, 4)
# => 
"""
      4月 2021
月  火  水  木  金  土  日
          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
"""

LocaleHTMLCalendar ロケール対応のHTMLでのカレンダー出力

from calendar import LocaleHTMLCalendar

l_html_cal = LocaleHTMLCalendar(locale='ja_JP')

print(l_html_cal.formatmonth(2021, 4))

以下はカレンダーの出力例です。

4月 2021
月火水木金土日
   1234
567891011
12131415161718
19202122232425
2627282930  

calendarの関数

import calendar
import locale

# ロケールを日本に設定
locale.setlocale(locale.LC_ALL, 'ja_JP.UTF-8')

# calendar.setfirstweekday(weekday) 週の最初の曜日(0:月曜日~6:日曜日)を設定
calendar.setfirstweekday(calendar.MONDAY)

# calendar.firstweekday() 週の最初の曜日
calendar.firstweekday() # => 0

# calendar.isleap(year) 閏年判定
calendar.isleap(2021) # => False

# calendar.leapdays(y1, y2) 指定年の範囲の閏年の回数
calendar.leapdays(1980, 2060) # => 20

# calendar.weekday(year, month, day) 指定日付の曜日 (0:月曜日~6:日曜日)
calendar.weekday(2021, 4, 1) # =>

# calendar.weekheader(n) 指定した長さで表現する曜日のヘッダ
for i in range(11):
    print(f"{i}: '{calendar.weekheader(i)}'")
# =>
# 0: '      '
# 1: '月 火 水 木 金 土 日'
# 2: '月  火  水  木  金  土  日 '
# 3: ' 月   火   水   木   金   土   日 '
# 4: ' 月    火    水    木    金    土    日  '
# 5: '  月     火     水     木     金     土     日  '
# 6: '  月      火      水      木      金      土      日   '
# 7: '   月       火       水       木       金       土       日   '
# 8: '   月        火        水        木        金        土        日    '
# 9: '   月曜日       火曜日       水曜日       木曜日       金曜日       土曜日       日曜日   '
# 10: '   月曜日        火曜日        水曜日        木曜日        金曜日        土曜日        日曜日    '

# calendar.monthrange(year, month) 指定月度の第1日の曜日と日数
calendar.monthrange(2021, 4) # => (3, 30)

# monthcalendar(year, month) 指定付きの日にちのリスト
calendar.monthcalendar(2021, 4)
# => 
# [[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, 0, 0]]

# calendar.prmonth(theyear, themonth, w=0, l=0) 指定月のカレンダーを出力 w:日の列幅、l:週の高さ
calendar.prmonth(2021, 4)

# calendar.month(theyear, themonth, w=0, l=0) 指定月のカレンダーの文字列 w:日の列幅、l:週の高さ
print(calendar.month(2021, 4))

# calendar.prcal(year, w=0, l=0, c=6, m=3) 1年間のカレンダーを出力
calendar.prcal(2021)

# calendar.calendar(year, w=2, l=1, c=6, m=3) 1年間のカレンダーを文字列で取得
print(calendar.calendar(2021))

# timegm(tuple) time.struct_time形式のタプルをタイムスタンプに変換
calendar.timegm((2021, 3, 28, 10, 6, 51, 6, 87, 0)) # => 1616926011

# ロケールの曜日
list(calendar.day_name) # => ['月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日', '日曜日']

# ロケールの省略曜日
list(calendar.day_abbr) # => ['月', '火', '水', '木', '金', '土', '日']

# ロケールの月
list(calendar.month_name) # => ['', '1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']

# ロケールの省略曜日
list(calendar.month_abbr) # => ['', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12']

(参考) calendar.timegmとtime.gmtime

calendar.timegmとtime.gmtimeは逆変換になっている。

import calendar
import time

calendar.timegm(time.gmtime(1616926011))
# => 1616926011

list(time.gmtime(calendar.timegm((2021, 3, 28, 10, 6, 51, 6, 87, 0))))
# => 2021, 3, 28, 10, 6, 51, 6, 87, 0]
Originally published at marusankakusikaku.jp
ツイッターでシェア
みんなに共有、忘れないようにメモ

maru3kaku4kaku

Pythonこつこつ学習中。よく忘れる。

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント