Pythonで月の日数・週数を取得
Pythonで任意の月の日数および週数(カレンダー上の週の数)を取得する方法について説明する。標準ライブラリのcalendarモジュールを利用する。
ここでは、カレンダー上の行の数をその月の週数としている。当然ながら、週の始まりを何曜日にするかによってその値は異なる。具体例は後述。
calendarモジュールを使ってテキストやHTMLのカレンダーを出力する方法については以下の記事を参照。
任意の月の日数を取得: calendar.monthrange()
calendar.monthrange()
関数は(月の初日の曜日, 月の日数)
のタプルを返す。曜日は月曜が0
、日曜が6
。第一引数に年、第二引数に月を指定する。
日数だけを取得したい場合はインデックス[1]
と指定すればよい(0始まりの1番目)。
import calendar
print(calendar.monthrange(2023, 1))
# (6, 31)
print(calendar.monthrange(2023, 1)[1])
# 31
もちろん、うるう年も考慮される。
- 関連記事: Pythonでうるう年を判定・カウント・列挙
print(calendar.monthrange(2023, 2)[1])
# 28
print(calendar.monthrange(2024, 2)[1])
# 29
なお、calendarモジュールには月の日数を直接返すcalendar._monthlen()
も定義されている。
ただし、calendar._monthlen()
は関数名がアンダースコアから始まっていることからも分かるように、モジュール内のみでの使用が意図されている。ドキュメントに記載されておらず、__all__
にも含まれていないので、calendar.monthrange()
を使うほうがよい。
print(calendar._monthlen(2023, 1))
# 31
print(calendar.__all__)
# ['IllegalMonthError', 'IllegalWeekdayError', 'setfirstweekday', 'firstweekday', 'isleap', 'leapdays', 'weekday', 'monthrange', 'monthcalendar', 'prmonth', 'month', 'prcal', 'calendar', 'timegm', 'month_name', 'month_abbr', 'day_name', 'day_abbr', 'Calendar', 'TextCalendar', 'HTMLCalendar', 'LocaleTextCalendar', 'LocaleHTMLCalendar', 'weekheader', 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY']
print('monthrange' in calendar.__all__)
# True
print('_monthlen' in calendar.__all__)
# False
任意の月の週数を取得
calendar.monthcalendar()
関数で、カレンダーを二次元リスト(リストのリスト)として取得できる。ここでは見やすいようにpprintを使っている。
- calendar.monthcalendar() --- 一般的なカレンダーに関する関数群 — Python 3.12.0 ドキュメント
- 関連記事: Pythonのpprintの使い方(リストや辞書を整形して出力)
import calendar
import pprint
print(calendar.month(2023, 1))
# January 2023
# 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
#
pprint.pprint(calendar.monthcalendar(2023, 1))
# [[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]]
カレンダー上の週の数はこの二次元リストに対して組み込み関数len()
を適用すると取得できる。
print(len(calendar.monthcalendar(2023, 1)))
# 6
週の始まりの曜日に注意
上の例のように、calendar.monthcalendar()
はデフォルトでは週の始まりを月曜日としてカレンダーを生成する。
週の始まりの曜日を変更したい場合はcalendar.setfirstweekday()
を使う。
calendar.setfirstweekday(calendar.SUNDAY)
print(calendar.month(2023, 1))
# January 2023
# 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
#
pprint.pprint(calendar.monthcalendar(2023, 1))
# [[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]]
print(len(calendar.monthcalendar(2023, 1)))
# 5
このように、週の始まりの曜日によって月に含まれる週の数は異なる場合があるので注意。
calendar.SUNDAY
などはただの整数。月曜calendar.MONDAY
が0
、日曜calendar.SUNDAY
が6
。calendar.setfirstweekday()
には整数値を指定してもよい。
現在の設定はcalendar.firstweekday()
で確認できる。
print(calendar.MONDAY)
# 0
print(calendar.SUNDAY)
# 6
calendar.setfirstweekday(0)
print(calendar.firstweekday())
# 0