note.nkmk.me

Pythonで任意の日付がその月の第何週目・何曜日かを取得

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

Pythonで任意の日付がその月の第何週目の何曜日かを算出し取得する方法について説明する。標準ライブラリのcalendarモジュールまたはdatetimeモジュールを利用する。

  • 月内の第n週目(週番号)の考え方
  • 任意の日付が第何何曜日(第nX曜日)かを取得
  • 任意の日付がカレンダー上の第何週目かを取得
スポンサーリンク

月内の第n週目(週番号)の考え方

ある日付がその月の第何週目とするかは、2通りの考え方がある。

以下のカレンダーを例とする。

import calendar
import datetime

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
# 

例えば2019年1月7日は、以下の2通りが考えられる。

  • 1番目=1週目の月曜日(第1月曜日)
  • カレンダー上の第2週目の月曜日

それぞれの場合の方法を示す。

任意の日付が第何何曜日(第nX曜日)かを取得

任意の日付が第何何曜日(第nX曜日)かを取得する方法は以下の通り。

calendarモジュールを使う場合。曜日はcalendar.weekday()で取得する。月曜0から日曜6までの整数値が返される。

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(2019, 1, 7))
# (1, 0)

print(get_nth_dow(2019, 1, 20))
# (3, 6)

この例では(第n週、X曜日)というタプルを返すようにしている。

datetimeモジュールを使う場合。曜日はdatetime.dateオブジェクトを生成しweekday()メソッドで取得する。返り値はcalendar.weekday()と同じく月曜0から日曜6までの整数値。

def get_nth_dow_datetime(year, month, day):
    return get_nth_week(day), datetime.date(year, month, day).weekday()

print(get_nth_dow_datetime(2019, 1, 7))
# (1, 0)

print(get_nth_dow_datetime(2019, 1, 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(2019, 1, 20)
print(get_nth_dow_datetime_dt(dt))
# (3, 6)

d = datetime.date(2019, 1, 20)
print(get_nth_dow_datetime_dt(d))
# (3, 6)

今の日時や今日の日付をdatetime.datetimeおよびdatetime.datetoday()メソッドで取得して引数とすることもできる。

print(datetime.date.today())
# 2019-07-29

print(get_nth_dow_datetime_dt(datetime.date.today()))
# (5, 0)

なお、反対に、ある月の第何何曜日(第nX曜日)の日付を取得したい場合は以下の記事を参照。

任意の日付がカレンダー上の第何週目かを取得

ある日付がカレンダー上の第何週目かを考える場合、週の始まりの曜日を考慮する必要がある。

月曜始まりのカレンダーと日曜始まりのカレンダーを例とする。

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
# 

calendar.setfirstweekday(6)
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
# 

例えば、2019年1月20日は、月曜始まりのカレンダーでは第3週目(3行目)だが、日曜始まりのカレンダーでは第4週目(4行目)となる。ちなみに、どちらの場合も第3日曜日(3番目の日曜日)であることは変わらない。

以下のようにオフセットを加える方法が考えられる。

calendarモジュールを使う場合。第四引数でカレンダー上の週の始まりの曜日を月曜0から日曜6までの整数値で指定する。

月初の曜日をcalendar.monthrange()の最初の要素で取得してオフセットを算出している。

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(2019, 1, 20))
# 3

print(get_nth_week2(2019, 1, 20, 6))
# 4

曜日も合わせて取得したい場合は、上の例のように複数の返り値を指定すればよい。以下の例でも同じ。

datetimeモジュールを使う場合。月初のdatetime.dateオブジェクトを生成し、weekday()メソッドで曜日を取得する。

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(2019, 1, 20))
# 3

print(get_nth_week2_datetime(2019, 1, 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(2019, 1, 20)
print(get_nth_week2_datetime_dt(dt))
# 3

print(get_nth_week2_datetime_dt(dt, 6))
# 4

d = datetime.date(2019, 1, 20)
print(get_nth_week2_datetime_dt(d))
# 3

print(get_nth_week2_datetime_dt(d, 6))
# 4

今の日時や今日の日付をdatetime.datetimeおよびdatetime.datetoday()メソッドで取得して引数とすることもできる。

print(datetime.date.today())
# 2019-07-29

print(get_nth_week2_datetime_dt(datetime.date.today()))
# 5

print(get_nth_week2_datetime_dt(datetime.date.today(), 6))
# 5
スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事