Pythonで任意の日付がその月の第何週目・何曜日かを取得
Pythonで任意の日付がその月の第何週目の何曜日かを算出し取得する方法について説明する。標準ライブラリのcalendarモジュールおよびdatetimeモジュールを利用する。
calendarモジュールやdatetimeモジュールの基本については以下の記事を参照。
- 関連記事: Pythonのcalendarでカレンダーを取得・出力(テキスト、HTMLなど)
- 関連記事: Pythonのdatetimeで日付や時間と文字列を変換(strftime, strptime)
月内の第n週目(週番号)の考え方
ある日付をその月の第何週目とするかは、2通りの考え方がある。
以下のカレンダーを例とする。
import calendar
print(calendar.month(2023, 8))
# August 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
#
例えば2023年8月7日は、以下の2通りが考えられる。
- 最初の月曜日(第1月曜日) = 第1週目の月曜日
- カレンダー上の第2週目の月曜日
それぞれの場合の方法を示す。
任意の日付が第何何曜日(第nX曜日)かを取得
任意の日付が第何何曜日(第nX曜日)かを取得する方法は以下の通り。
calendarモジュールを使う場合。曜日はcalendar.weekday()
で取得する。月曜0
から日曜6
までの整数値が返される。
import calendar
def get_nth_week(day):
return (day - 1) // 7 + 1
def get_nth_dow(year, month, day):
return get_nth_week(day), calendar.weekday(year, month, day)
print(get_nth_dow(2023, 8, 7))
# (1, 0)
print(get_nth_dow(2023, 8, 20))
# (3, 6)
この例では(第n週、X曜日)
というタプルを返すようにしている。
- 関連記事: Pythonの関数で複数の戻り値を返す方法
datetimeモジュールを使う場合。曜日はdatetime.date
オブジェクトのweekday()
メソッドで取得する。返り値はcalendar.weekday()
と同じく月曜0
から日曜6
までの整数値。
import datetime
def get_nth_dow_datetime(year, month, day):
return get_nth_week(day), datetime.date(year, month, day).weekday()
print(get_nth_dow_datetime(2023, 8, 7))
# (1, 0)
print(get_nth_dow_datetime(2023, 8, 20))
# (3, 6)
datetime.datetime
オブジェクトやdatetime.date
オブジェクトを引数とする場合。weekday()
メソッドはどちらの型でも使用可能。
def get_nth_dow_datetime_dt(dt):
return get_nth_week(dt.day), dt.weekday()
dt = datetime.datetime(2023, 8, 20)
print(get_nth_dow_datetime_dt(dt))
# (3, 6)
d = datetime.date(2023, 8, 20)
print(get_nth_dow_datetime_dt(d))
# (3, 6)
今の日時や今日の日付をdatetime.datetime
のnow()
メソッドやdatetime.date
のtoday()
メソッドで取得して引数とすることもできる。
- 関連記事: Pythonで現在時刻・日付・日時を取得
print(datetime.date.today())
# 2023-10-11
print(get_nth_dow_datetime_dt(datetime.date.today()))
# (2, 2)
反対に、ある月の第何何曜日(第nX曜日)の日付を取得したい場合は以下の記事を参照。
任意の日付がカレンダー上の第何週目かを取得
ある日付がカレンダー上の第何週目かを取得する場合、週の始まりの曜日を考慮する必要がある。
月曜始まりのカレンダーと日曜始まりのカレンダーを例とする。
import calendar
print(calendar.month(2023, 8))
# August 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
#
calendar.setfirstweekday(6)
print(calendar.month(2023, 8))
# August 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
#
例えば、2023年8月20日は、月曜始まりのカレンダーでは第3週目(3行目)だが、日曜始まりのカレンダーでは第4週目(4行目)となる。ちなみに、どちらの場合も第3日曜日(3番目の日曜日)であることは変わらない。
以下のようにオフセットを加える方法が考えられる。
calendarモジュールを使う場合。第四引数でカレンダー上の週の始まりの曜日を月曜0
から日曜6
までの整数値で指定する。
月初の曜日をcalendar.monthrange()
の最初の要素で取得してオフセットを算出している。
- 関連記事: Pythonで月の日数・週数を取得
def get_nth_week2(year, month, day, firstweekday=0):
first_dow = calendar.monthrange(year, month)[0]
offset = (first_dow - firstweekday) % 7
return (day + offset - 1) // 7 + 1
print(get_nth_week2(2023, 8, 20))
# 3
print(get_nth_week2(2023, 8, 20, 6))
# 4
曜日も合わせて取得したい場合は、上の例のように複数の返り値を指定すればよい。以下の例でも同じ。
datetimeモジュールを使う場合。月初のdatetime.date
オブジェクトを生成し、weekday()
メソッドで曜日を取得する。
import datetime
def get_nth_week2_datetime(year, month, day, firstweekday=0):
first_dow = datetime.date(year, month, 1).weekday()
offset = (first_dow - firstweekday) % 7
return (day + offset - 1) // 7 + 1
print(get_nth_week2_datetime(2023, 8, 20))
# 3
print(get_nth_week2_datetime(2023, 8, 20, 6))
# 4
datetime.datetime
オブジェクトやdatetime.date
オブジェクトを引数とする場合。replace()
で日にちを1
に置換して月初のオブジェクトを生成し、weekday()
メソッドで曜日を取得する。
def get_nth_week2_datetime_dt(dt, firstweekday=0):
first_dow = dt.replace(day=1).weekday()
offset = (first_dow - firstweekday) % 7
return (dt.day + offset - 1) // 7 + 1
dt = datetime.datetime(2023, 8, 20)
print(get_nth_week2_datetime_dt(dt))
# 3
print(get_nth_week2_datetime_dt(dt, 6))
# 4
d = datetime.date(2023, 8, 20)
print(get_nth_week2_datetime_dt(d))
# 3
print(get_nth_week2_datetime_dt(d, 6))
# 4
今の日時や今日の日付をdatetime.datetime
およびdatetime.date
のtoday()
メソッドで取得して引数とすることもできる。
print(datetime.date.today())
# 2023-10-11
print(get_nth_week2_datetime_dt(datetime.date.today()))
# 3
print(get_nth_week2_datetime_dt(datetime.date.today(), 6))
# 2