note.nkmk.me

Pythonのcalendarでカレンダーを取得・出力(テキスト、HTMLなど)

Date: 2019-07-28 / tags: Python, 日時処理

Pythonの標準ライブラリcalendarモジュールで、カレンダーをプレーンテキストやHTML、数値のリストなどとして生成し取得・出力することができる。

ここでは以下の内容について説明する。

  • カレンダーをプレーンテキストで取得・出力
    • 月間カレンダー
    • 年間カレンダー
    • 週の始まりの曜日を設定
    • ロケールを変更して曜日の文字列を変更
  • カレンダーをHTMLで取得
    • 月間カレンダー
    • 年間カレンダー
    • CSSのクラスを設定
    • 週の始まりの曜日を設定
    • ロケールを変更して曜日の文字列を変更
  • カレンダーをリストで取得
    • 数値のリスト
    • タプルのリスト
    • datretime.dateのリスト
  • コマンドラインで利用

日時を扱う標準ライブラリとして、ほかにdatetimeモジュールがある。

また、calendarモジュールには、うるう年を判定したり、月の日数を取得したりする便利な関数も用意されている。

スポンサーリンク

カレンダーをプレーンテキストで取得・出力

月間カレンダー

calendar.month()で任意の年・月のカレンダーを文字列(str型)で取得できる。

import calendar

print(calendar.month(2019, 1))
#     January 2019
# 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
# 

print(type(calendar.month(2019, 1)))
# <class 'str'>

引数wで列幅、引数lで行幅を指定可能。

print(calendar.month(2019, 1, w=3, l=2))
#         January 2019
# 
# Mon Tue Wed Thu Fri Sat Sun
# 
#       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
# 
# 

calendar.prmonth()で同様の文字列を標準出力できる。ここでは省略しているが、引数w, lを指定可能。

calendar.prmonth(2019, 1)
#     January 2019
# 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

年間カレンダー

年間カレンダーはcalendar.calendar()。引数に年を指定する。

print(calendar.calendar(2019))
#                                   2019
# 
#       January                   February                   March
# Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
#     1  2  3  4  5  6                   1  2  3                   1  2  3
#  7  8  9 10 11 12 13       4  5  6  7  8  9 10       4  5  6  7  8  9 10
# 14 15 16 17 18 19 20      11 12 13 14 15 16 17      11 12 13 14 15 16 17
# 21 22 23 24 25 26 27      18 19 20 21 22 23 24      18 19 20 21 22 23 24
# 28 29 30 31               25 26 27 28               25 26 27 28 29 30 31
# 
#        April                      May                       June
# Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
#  1  2  3  4  5  6  7             1  2  3  4  5                      1  2
#  8  9 10 11 12 13 14       6  7  8  9 10 11 12       3  4  5  6  7  8  9
# 15 16 17 18 19 20 21      13 14 15 16 17 18 19      10 11 12 13 14 15 16
# 22 23 24 25 26 27 28      20 21 22 23 24 25 26      17 18 19 20 21 22 23
# 29 30                     27 28 29 30 31            24 25 26 27 28 29 30
# 
#         July                     August                  September
# Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
#  1  2  3  4  5  6  7                1  2  3  4                         1
#  8  9 10 11 12 13 14       5  6  7  8  9 10 11       2  3  4  5  6  7  8
# 15 16 17 18 19 20 21      12 13 14 15 16 17 18       9 10 11 12 13 14 15
# 22 23 24 25 26 27 28      19 20 21 22 23 24 25      16 17 18 19 20 21 22
# 29 30 31                  26 27 28 29 30 31         23 24 25 26 27 28 29
#                                                     30
# 
#       October                   November                  December
# Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
#     1  2  3  4  5  6                   1  2  3                         1
#  7  8  9 10 11 12 13       4  5  6  7  8  9 10       2  3  4  5  6  7  8
# 14 15 16 17 18 19 20      11 12 13 14 15 16 17       9 10 11 12 13 14 15
# 21 22 23 24 25 26 27      18 19 20 21 22 23 24      16 17 18 19 20 21 22
# 28 29 30 31               25 26 27 28 29 30         23 24 25 26 27 28 29
#                                                     30 31
# 

print(type(calendar.calendar(2019)))
# <class 'str'>

引数mで1行に出力する月の数を指定可能。デフォルトは1行に3つの月(3列)。さらに引数cで月の間のスペースの数を指定できる。以下の例では省略しているが、calendar.month()と同様に各月内の行幅や列幅を引数w, lで指定可能。

print(calendar.calendar(2019, c=3, m=4))
#                                            2019
# 
#       January                February                March                  April
# Mo Tu We Th Fr Sa Su   Mo Tu We Th Fr Sa Su   Mo Tu We Th Fr Sa Su   Mo Tu We Th Fr Sa Su
#     1  2  3  4  5  6                1  2  3                1  2  3    1  2  3  4  5  6  7
#  7  8  9 10 11 12 13    4  5  6  7  8  9 10    4  5  6  7  8  9 10    8  9 10 11 12 13 14
# 14 15 16 17 18 19 20   11 12 13 14 15 16 17   11 12 13 14 15 16 17   15 16 17 18 19 20 21
# 21 22 23 24 25 26 27   18 19 20 21 22 23 24   18 19 20 21 22 23 24   22 23 24 25 26 27 28
# 28 29 30 31            25 26 27 28            25 26 27 28 29 30 31   29 30
# 
#         May                    June                   July                  August
# Mo Tu We Th Fr Sa Su   Mo Tu We Th Fr Sa Su   Mo Tu We Th Fr Sa Su   Mo Tu We Th Fr Sa Su
#        1  2  3  4  5                   1  2    1  2  3  4  5  6  7             1  2  3  4
#  6  7  8  9 10 11 12    3  4  5  6  7  8  9    8  9 10 11 12 13 14    5  6  7  8  9 10 11
# 13 14 15 16 17 18 19   10 11 12 13 14 15 16   15 16 17 18 19 20 21   12 13 14 15 16 17 18
# 20 21 22 23 24 25 26   17 18 19 20 21 22 23   22 23 24 25 26 27 28   19 20 21 22 23 24 25
# 27 28 29 30 31         24 25 26 27 28 29 30   29 30 31               26 27 28 29 30 31
# 
#      September               October                November               December
# Mo Tu We Th Fr Sa Su   Mo Tu We Th Fr Sa Su   Mo Tu We Th Fr Sa Su   Mo Tu We Th Fr Sa Su
#                    1       1  2  3  4  5  6                1  2  3                      1
#  2  3  4  5  6  7  8    7  8  9 10 11 12 13    4  5  6  7  8  9 10    2  3  4  5  6  7  8
#  9 10 11 12 13 14 15   14 15 16 17 18 19 20   11 12 13 14 15 16 17    9 10 11 12 13 14 15
# 16 17 18 19 20 21 22   21 22 23 24 25 26 27   18 19 20 21 22 23 24   16 17 18 19 20 21 22
# 23 24 25 26 27 28 29   28 29 30 31            25 26 27 28 29 30      23 24 25 26 27 28 29
# 30                                                                   30 31
# 

calendar.prcal()で同様の文字列を標準出力できる。引数w, l, c, mを指定可能。 ここでは出力結果は省略。

calendar.prcal(2019)

週の始まりの曜日を設定

これまでの例のように、デフォルトは月曜始まり。

calendar.setfirstweekday()で任意の曜日に変更できる。

calendar.setfirstweekday(calendar.SUNDAY)

print(calendar.month(2019, 1))
#     January 2019
# 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
# 

calendar.MONDAYcalendar.SUNDAYはただの整数。calendar.setfirstweekday()に整数値を指定しても問題ない。現在の設定はcalendar.firstweekday()で確認できる。

print(calendar.MONDAY)
# 0

print(calendar.SUNDAY)
# 6

calendar.setfirstweekday(0)

print(calendar.month(2019, 1))
#     January 2019
# 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
# 

print(calendar.firstweekday())
# 0

ロケールを変更して曜日の文字列を変更

曜日を表す文字列はロケールに依存する。

任意のロケールを指定してcalendar.LocaleTextCalendarオブジェクトを生成し各種メソッドを実行することで、そのロケールに対応した文字列で曜日を出力できる。以下はドイツ語の例。

ltc_de = calendar.LocaleTextCalendar(locale='de_de')

print(ltc_de.formatmonth(2019, 1))
#     Januar 2019
# Mo Di Mi Do Fr Sa So
#     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
# 

calendar.LocaleTextCalendarオブジェクトには以下のメソッドがある。月間カレンダーには引数w, lを、年間カレンダーにはさらに引数c, mを指定できる。

  • formatmonth(): 月間カレンダーの文字列を返す
  • prmonth(): 月間カレンダーを標準出力
  • formatyear(): 年間カレンダーの文字列を返す
  • pryear(): 年間カレンダーを標準出力

全角文字の幅は考慮されておらず、日本語の場合はレイアウトが崩れてしまうので注意。

ltc_ja = calendar.LocaleTextCalendar(locale='ja_jp')

print(ltc_ja.formatmonth(2019, 1))
#       1月 2019
# 月  火  水  木  金  土  日
#     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で取得

カレンダーをHTML形式の文字列を生成し取得できる。テーブル<table>として表現される。

calendar.HTMLCalendarオブジェクトを生成し、各種メソッドを実行する。

hc = calendar.HTMLCalendar()

月間カレンダー

月間カレンダーはformatmonth()。引数withyearでヘッダーに年を表示するかを指定可能。デフォルトはTrue

print(hc.formatmonth(2019, 1, withyear=False))
# <table border="0" cellpadding="0" cellspacing="0" class="month">
# <tr><th colspan="7" class="month">January</th></tr>
# <tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
# <tr><td class="noday">&nbsp;</td><td class="tue">1</td><td class="wed">2</td><td class="thu">3</td><td class="fri">4</td><td class="sat">5</td><td class="sun">6</td></tr>
# <tr><td class="mon">7</td><td class="tue">8</td><td class="wed">9</td><td class="thu">10</td><td class="fri">11</td><td class="sat">12</td><td class="sun">13</td></tr>
# <tr><td class="mon">14</td><td class="tue">15</td><td class="wed">16</td><td class="thu">17</td><td class="fri">18</td><td class="sat">19</td><td class="sun">20</td></tr>
# <tr><td class="mon">21</td><td class="tue">22</td><td class="wed">23</td><td class="thu">24</td><td class="fri">25</td><td class="sat">26</td><td class="sun">27</td></tr>
# <tr><td class="mon">28</td><td class="tue">29</td><td class="wed">30</td><td class="thu">31</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td></tr>
# </table>
# 

print(type(hc.formatmonth(2019, 1)))
# <class 'str'>

年間カレンダー

年間カレンダーはformatyear()。引数widthで1行に表示する月の数を指定可能。デフォルトは3

出力結果は省略する。

print(hc.formatyear(2019, width=4))

CSSのクラスを設定

これまでの例の出力結果のように、各曜日にCSSのクラスが設定されている。

このクラス名はcssclasses属性にリストとして格納されている。新たなリストを代入することで変更可能。変更後、formatmonth()formatyear()を実行すると、それらのクラス名を使ったHTMLが取得できる。

print(hc.cssclasses)
# ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']

hc.cssclasses = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat blue', 'sun red']

Python3.7からは、存在しない日や、月、年に対するCSSクラスの属性も追加された。これも新たな値に変更可能。

print(hc.cssclass_month)
# month

print(hc.cssclass_year)
# year

print(hc.cssclass_noday)
# noday

週の始まりの曜日を設定

週の始まりの曜日はコンストラクタcalendar.HTMLCalendar()の引数で指定する。

hc_sun = calendar.HTMLCalendar(firstweekday=6)

print(hc_sun.formatmonth(2019, 1))
# <table border="0" cellpadding="0" cellspacing="0" class="month">
# <tr><th colspan="7" class="month">January 2019</th></tr>
# <tr><th class="sun">Sun</th><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th></tr>
# <tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="tue">1</td><td class="wed">2</td><td class="thu">3</td><td class="fri">4</td><td class="sat">5</td></tr>
# <tr><td class="sun">6</td><td class="mon">7</td><td class="tue">8</td><td class="wed">9</td><td class="thu">10</td><td class="fri">11</td><td class="sat">12</td></tr>
# <tr><td class="sun">13</td><td class="mon">14</td><td class="tue">15</td><td class="wed">16</td><td class="thu">17</td><td class="fri">18</td><td class="sat">19</td></tr>
# <tr><td class="sun">20</td><td class="mon">21</td><td class="tue">22</td><td class="wed">23</td><td class="thu">24</td><td class="fri">25</td><td class="sat">26</td></tr>
# <tr><td class="sun">27</td><td class="mon">28</td><td class="tue">29</td><td class="wed">30</td><td class="thu">31</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td></tr>
# </table>
# 

calendar.setfirstweekday()は効かないので注意。

ロケールを変更して曜日の文字列を変更

ロケールを変更したい場合は、calendar.LocaleHTMLCalendarオブジェクトを生成する。メソッドはcalendar.HTMLCalendarオブジェクトと同じ。

lhc = calendar.LocaleHTMLCalendar(firstweekday=6, locale='ja_jp')

print(lhc.formatmonth(2019, 1))
# <table border="0" cellpadding="0" cellspacing="0" class="month">
# <tr><th colspan="7" class="month">1月 2019</th></tr>
# <tr><th class="sun">日</th><th class="mon">月</th><th class="tue">火</th><th class="wed">水</th><th class="thu">木</th><th class="fri">金</th><th class="sat">土</th></tr>
# <tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="tue">1</td><td class="wed">2</td><td class="thu">3</td><td class="fri">4</td><td class="sat">5</td></tr>
# <tr><td class="sun">6</td><td class="mon">7</td><td class="tue">8</td><td class="wed">9</td><td class="thu">10</td><td class="fri">11</td><td class="sat">12</td></tr>
# <tr><td class="sun">13</td><td class="mon">14</td><td class="tue">15</td><td class="wed">16</td><td class="thu">17</td><td class="fri">18</td><td class="sat">19</td></tr>
# <tr><td class="sun">20</td><td class="mon">21</td><td class="tue">22</td><td class="wed">23</td><td class="thu">24</td><td class="fri">25</td><td class="sat">26</td></tr>
# <tr><td class="sun">27</td><td class="mon">28</td><td class="tue">29</td><td class="wed">30</td><td class="thu">31</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td></tr>
# </table>
# 

カレンダーをリストで取得

数値のリスト

calendar.monthcalendar()で要素が日付の整数となる2次元のリスト(リストのリスト)でカレンダーを取得できる。存在しない日は0となる。

ここではpprintを使って見やすく出力している。

import calendar
import pprint

pprint.pprint(calendar.monthcalendar(2019, 1))
# [[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]]

calendar.setfirstweekday()で週の始まりの曜日を指定可能。

calendar.setfirstweekday(6)

pprint.pprint(calendar.monthcalendar(2019, 1))
# [[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]]

calendar.Calendarオブジェクトを生成し、monthdayscalendar()メソッドを呼んでも同様のリストが得られる。この方法の場合。コンストラクタcalendar.Calendar()の引数firstweekdayで週の始まりの曜日を指定できる。

c = calendar.Calendar(firstweekday=0)

pprint.pprint(c.monthdayscalendar(2019, 1))
# [[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]]

calendar.Calendarオブジェクトのyeardayscalendar()メソッドで、年間カレンダーを取得できる。プレーンテキストやHTMLの場合と同様、各月が縦横に行列状に配置される。引数widthで1行の月の数を指定可能。デフォルトはwidth=3

pprintの機能(引数depth)で省略された部分[...]に各月のリストが格納されている。

pprint.pprint(c.yeardayscalendar(2019), depth=2)
# [[[...], [...], [...]],
#  [[...], [...], [...]],
#  [[...], [...], [...]],
#  [[...], [...], [...]]]

pprint.pprint(c.yeardayscalendar(2019, width=4), depth=2)
# [[[...], [...], [...], [...]],
#  [[...], [...], [...], [...]],
#  [[...], [...], [...], [...]]]

タプルのリスト

calendar.Calendarmonthdays2calendar()で、タプルを要素とするカレンダーをリストで取得できる。各タプルは(日付, 曜日)の値を持つ。存在しない日付は0

pprint.pprint(c.monthdays2calendar(2019, 1))
# [[(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)]]

年間カレンダーはyeardays2calendar()。例は省略。

datretime.dateのリスト

calendar.Calendarmonthdatescalendar()で、datetime.dateを要素とするカレンダーをリストで取得できる。

初週および最終週は前月・次月の値も含む。

pprint.pprint(c.monthdatescalendar(2019, 1))
# [[datetime.date(2018, 12, 31),
#   datetime.date(2019, 1, 1),
#   datetime.date(2019, 1, 2),
#   datetime.date(2019, 1, 3),
#   datetime.date(2019, 1, 4),
#   datetime.date(2019, 1, 5),
#   datetime.date(2019, 1, 6)],
#  [datetime.date(2019, 1, 7),
#   datetime.date(2019, 1, 8),
#   datetime.date(2019, 1, 9),
#   datetime.date(2019, 1, 10),
#   datetime.date(2019, 1, 11),
#   datetime.date(2019, 1, 12),
#   datetime.date(2019, 1, 13)],
#  [datetime.date(2019, 1, 14),
#   datetime.date(2019, 1, 15),
#   datetime.date(2019, 1, 16),
#   datetime.date(2019, 1, 17),
#   datetime.date(2019, 1, 18),
#   datetime.date(2019, 1, 19),
#   datetime.date(2019, 1, 20)],
#  [datetime.date(2019, 1, 21),
#   datetime.date(2019, 1, 22),
#   datetime.date(2019, 1, 23),
#   datetime.date(2019, 1, 24),
#   datetime.date(2019, 1, 25),
#   datetime.date(2019, 1, 26),
#   datetime.date(2019, 1, 27)],
#  [datetime.date(2019, 1, 28),
#   datetime.date(2019, 1, 29),
#   datetime.date(2019, 1, 30),
#   datetime.date(2019, 1, 31),
#   datetime.date(2019, 2, 1),
#   datetime.date(2019, 2, 2),
#   datetime.date(2019, 2, 3)]]

datetime.dateは標準ライブラリdatetimeモジュールの型で、年月日を表す。

年間カレンダーはyeardatescalendar()。例は省略。

コマンドラインで利用

calendarモジュールはコマンドラインからも利用できるようになっている。

コマンドラインで、pythonコマンド(環境によってはpython3)に-mオプションをつけてモジュールとしてcalendarを呼び出す。

python3 -m calendar 2019 1
#     January 2019
# 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

各種オプションも使用可能。以下はヘルプの出力。

python3 -m calendar -h
# usage: calendar.py [-h] [-w WIDTH] [-l LINES] [-s SPACING] [-m MONTHS]
#                    [-c CSS] [-L LOCALE] [-e ENCODING] [-t {text,html}]
#                    [year] [month]
# 
# positional arguments:
#   year                  year number (1-9999)
#   month                 month number (1-12, text only)
# 
# optional arguments:
#   -h, --help            show this help message and exit
#   -L LOCALE, --locale LOCALE
#                         locale to be used from month and weekday names
#   -e ENCODING, --encoding ENCODING
#                         encoding to use for output
#   -t {text,html}, --type {text,html}
#                         output type (text or html)
# 
# text only arguments:
#   -w WIDTH, --width WIDTH
#                         width of date column (default 2)
#   -l LINES, --lines LINES
#                         number of lines for each week (default 1)
#   -s SPACING, --spacing SPACING
#                         spacing between months (default 6)
#   -m MONTHS, --months MONTHS
#                         months per row (default 3)
# 
# html only arguments:
#   -c CSS, --css CSS     CSS to use for page
スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事