Pythonで月の日数・週数を取得

Modified: | Tags: 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

もちろん、うるう年も考慮される。

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を使っている。

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.MONDAY0、日曜calendar.SUNDAY6calendar.setfirstweekday()には整数値を指定してもよい。

現在の設定はcalendar.firstweekday()で確認できる。

print(calendar.MONDAY)
# 0

print(calendar.SUNDAY)
# 6

calendar.setfirstweekday(0)

print(calendar.firstweekday())
# 0

関連カテゴリー

関連記事