calendar – 日付の処理¶
目的: | calendar モジュールは年/月/週を管理する日付を処理するクラスを実装する |
---|---|
利用できるバージョン: | 1.4 で追加、2.5 で拡張 |
calendar モジュールは、特定の月または年のある週の日付といった計算をカプセル化する Calendar クラスを定義します。さらに TextCalendar と HTMLCalendar クラスは、フォーマット済みの出力を生成できます。
フォーマットサンプル¶
TextCalendar を使用して、ある月のフォーマット済みのテキスト出力を生成するには prmonth() メソッドがとても簡単です。
import calendar
c = calendar.TextCalendar(calendar.SUNDAY)
c.prmonth(2007, 7)
このサンプルはアメリカの規則に従い、週が日曜日から始まるように TextCalendar を設定します。デフォルトは、週が月曜日から始まるヨーロッパの規則を使用します。
次のような結果になります。
$ python calendar_textcalendar.py
July 2007
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 出力は、 prmonth() メソッドがないのでわずかに違います。
import calendar
c = calendar.HTMLCalendar(calendar.SUNDAY)
print c.formatmonth(2007, 7)
レンダリングされた HTML 出力は大まかに同じように見えますが、HTML タグで囲まれます。さらにテーブルの各セルは、曜日に対するクラス属性をもちます。
$ python calendar_htmlcalendar.py
<table border="0" cellpadding="0" cellspacing="0" class="month">
<tr><th colspan="7" class="month">July 2007</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="sun">1</td><td class="mon">2</td><td class="tue">3</td><td class="wed">4</td><td class="thu">5</td><td class="fri">6</td><td class="sat">7</td></tr>
<tr><td class="sun">8</td><td class="mon">9</td><td class="tue">10</td><td class="wed">11</td><td class="thu">12</td><td class="fri">13</td><td class="sat">14</td></tr>
<tr><td class="sun">15</td><td class="mon">16</td><td class="tue">17</td><td class="wed">18</td><td class="thu">19</td><td class="fri">20</td><td class="sat">21</td></tr>
<tr><td class="sun">22</td><td class="mon">23</td><td class="tue">24</td><td class="wed">25</td><td class="thu">26</td><td class="fri">27</td><td class="sat">28</td></tr>
<tr><td class="sun">29</td><td class="mon">30</td><td class="tue">31</td><td class="noday"> </td><td class="noday"> </td><td class="noday"> </td><td class="noday"> </td></tr>
</table>
デフォルトで利用できるフォーマット以外の出力を生成する必要がある場合、 calendar で週と月の範囲に値をセットして日付を計算できます。そして、その実行結果を繰り返し処理できます。 Calendar の weekheader(), monthcalendar(), yeardays2calendar() メソッドは、特にそういった処理に便利です。
yeardays2calendar() を呼び出すと、”月の行” のリストのシーケンスを生成します。それぞのリストには、週毎のリストが含まれています。週は日(1-31)と曜日(0-6)で構成されるタプルのリストです。その月に存在しない日は0になります。
import calendar
import pprint
pprint.pprint(calendar.Calendar(calendar.SUNDAY).yeardays2calendar(2007, 2))
yeardays2calendar(2007、2) を呼び出すと、2007年の1行につき2ヶ月分を構成するデータを返します。
$ python calendar_yeardays2calendar.py
[[[[(0, 6), (1, 0), (2, 1), (3, 2), (4, 3), (5, 4), (6, 5)],
[(7, 6), (8, 0), (9, 1), (10, 2), (11, 3), (12, 4), (13, 5)],
[(14, 6), (15, 0), (16, 1), (17, 2), (18, 3), (19, 4), (20, 5)],
[(21, 6), (22, 0), (23, 1), (24, 2), (25, 3), (26, 4), (27, 5)],
[(28, 6), (29, 0), (30, 1), (31, 2), (0, 3), (0, 4), (0, 5)]],
[[(0, 6), (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), (0, 3), (0, 4), (0, 5)]]],
[[[(0, 6), (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), (31, 5)]],
[[(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), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5)]]],
[[[(0, 6), (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), (0, 0), (0, 1), (0, 2), (0, 3), (1, 4), (2, 5)],
[(3, 6), (4, 0), (5, 1), (6, 2), (7, 3), (8, 4), (9, 5)],
[(10, 6), (11, 0), (12, 1), (13, 2), (14, 3), (15, 4), (16, 5)],
[(17, 6), (18, 0), (19, 1), (20, 2), (21, 3), (22, 4), (23, 5)],
[(24, 6), (25, 0), (26, 1), (27, 2), (28, 3), (29, 4), (30, 5)]]],
[[[(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)]],
[[(0, 6), (0, 0), (0, 1), (1, 2), (2, 3), (3, 4), (4, 5)],
[(5, 6), (6, 0), (7, 1), (8, 2), (9, 3), (10, 4), (11, 5)],
[(12, 6), (13, 0), (14, 1), (15, 2), (16, 3), (17, 4), (18, 5)],
[(19, 6), (20, 0), (21, 1), (22, 2), (23, 3), (24, 4), (25, 5)],
[(26, 6), (27, 0), (28, 1), (29, 2), (30, 3), (31, 4), (0, 5)]]],
[[[(0, 6), (0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (1, 5)],
[(2, 6), (3, 0), (4, 1), (5, 2), (6, 3), (7, 4), (8, 5)],
[(9, 6), (10, 0), (11, 1), (12, 2), (13, 3), (14, 4), (15, 5)],
[(16, 6), (17, 0), (18, 1), (19, 2), (20, 3), (21, 4), (22, 5)],
[(23, 6), (24, 0), (25, 1), (26, 2), (27, 3), (28, 4), (29, 5)],
[(30, 6), (0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5)]],
[[(0, 6), (1, 0), (2, 1), (3, 2), (4, 3), (5, 4), (6, 5)],
[(7, 6), (8, 0), (9, 1), (10, 2), (11, 3), (12, 4), (13, 5)],
[(14, 6), (15, 0), (16, 1), (17, 2), (18, 3), (19, 4), (20, 5)],
[(21, 6), (22, 0), (23, 1), (24, 2), (25, 3), (26, 4), (27, 5)],
[(28, 6), (29, 0), (30, 1), (31, 2), (0, 3), (0, 4), (0, 5)]]],
[[[(0, 6), (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), (0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (1, 5)],
[(2, 6), (3, 0), (4, 1), (5, 2), (6, 3), (7, 4), (8, 5)],
[(9, 6), (10, 0), (11, 1), (12, 2), (13, 3), (14, 4), (15, 5)],
[(16, 6), (17, 0), (18, 1), (19, 2), (20, 3), (21, 4), (22, 5)],
[(23, 6), (24, 0), (25, 1), (26, 2), (27, 3), (28, 4), (29, 5)],
[(30, 6), (31, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5)]]]]
これは formatyear() が使用するデータと同じです。
import calendar
print calendar.TextCalendar(calendar.SUNDAY).formatyear(2007, 2, 1, 1, 2)
同じ引数を渡すと次のような出力を生成します。
$ python calendar_formatyear.py
2007
January February
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 2 3 4 5 6 1 2 3
7 8 9 10 11 12 13 4 5 6 7 8 9 10
14 15 16 17 18 19 20 11 12 13 14 15 16 17
21 22 23 24 25 26 27 18 19 20 21 22 23 24
28 29 30 31 25 26 27 28
March April
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 2 3 1 2 3 4 5 6 7
4 5 6 7 8 9 10 8 9 10 11 12 13 14
11 12 13 14 15 16 17 15 16 17 18 19 20 21
18 19 20 21 22 23 24 22 23 24 25 26 27 28
25 26 27 28 29 30 31 29 30
May June
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 2 3 4 5 1 2
6 7 8 9 10 11 12 3 4 5 6 7 8 9
13 14 15 16 17 18 19 10 11 12 13 14 15 16
20 21 22 23 24 25 26 17 18 19 20 21 22 23
27 28 29 30 31 24 25 26 27 28 29 30
July August
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
8 9 10 11 12 13 14 5 6 7 8 9 10 11
15 16 17 18 19 20 21 12 13 14 15 16 17 18
22 23 24 25 26 27 28 19 20 21 22 23 24 25
29 30 31 26 27 28 29 30 31
September October
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 1 2 3 4 5 6
2 3 4 5 6 7 8 7 8 9 10 11 12 13
9 10 11 12 13 14 15 14 15 16 17 18 19 20
16 17 18 19 20 21 22 21 22 23 24 25 26 27
23 24 25 26 27 28 29 28 29 30 31
30
November December
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 2 3 1
4 5 6 7 8 9 10 2 3 4 5 6 7 8
11 12 13 14 15 16 17 9 10 11 12 13 14 15
18 19 20 21 22 23 24 16 17 18 19 20 21 22
25 26 27 28 29 30 23 24 25 26 27 28 29
30 31
(HTML 出力にリンクを含めるといった)何らかの理由から自分で出力をフォーマットしたい場合、 day_name, day_abbr, month_name, month_abbr のモジュール属性が便利です。カレントロケールを検出して自動的に正しい設定を行ってくれます。
日付計算¶
calendar モジュールは、様々なフォーマットで完全なカレンダーを表示することを主な機能としていますが、その他にも定期的なイベント日程を計算するといった、日付を処理するのにも便利な関数も提供します。例えば、Python アトランタユーザグループは毎月第2木曜日にミーティングを行っています。年間のミーティング日程を計算するには monthcalendar() の返り値を使用できます。
import calendar
import pprint
pprint.pprint(calendar.monthcalendar(2007, 7))
日によっては 0 があることに注目してください。0 の日は指定された月が別の月と重複する週の日です。
$ python calendar_monthcalendar.py
[[0, 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]]
前節で説明したように週の最初の日は月曜日です。週の最初の曜日は setfirstweekday() を呼び出すことで変更できます。別の方法としては、 calendar モジュールは monthcalendar() が返す日付の範囲にインデクシングするための定数を含むので、この場合はその手順を省略してかなり便利です。
毎月第2木曜日と仮定した 2007 年の PyATL ミーティングの日程を計算するには、その月の最初の週に木曜日が含まれるかどうか(もしくは、月の最初の日が金曜日か等)を調べるのに 0 の値を使用できます。
import calendar
# 全ての月を表示する
for month in range(1, 13):
# その月と重複するそれぞれの週の日付を計算する
c = calendar.monthcalendar(2007, month)
first_week = c[0]
second_week = c[1]
third_week = c[2]
# 最初の週に木曜日がある場合、第2木曜日は2番目の週になる
# それ以外は第3週にある
if first_week[calendar.THURSDAY]:
meeting_date = second_week[calendar.THURSDAY]
else:
meeting_date = third_week[calendar.THURSDAY]
print '%3s: %2s' % (month, meeting_date)
2007 年の PyATL ミーティングのスケジュールは次になります。
$ python calendar_secondthursday.py
1: 11
2: 8
3: 8
4: 12
5: 10
6: 14
7: 12
8: 9
9: 13
10: 11
11: 8
12: 13