Pythonで月初・月末(初日・最終日)、最終X曜日の日付を取得
Pythonで、月初・月末(月の初日・最終日)および最終X曜日(最終月曜日、最終金曜日など)の日付(年月日)を、datetime.datetime
やdatetime.date
として取得する方法を説明する。
標準ライブラリのdatetimeモジュールおよびcalendarモジュールを使う。
- 関連記事: Pythonのdatetimeで日付や時間と文字列を変換(strftime, strptime)
- 関連記事: Pythonのcalendarでカレンダーを取得・出力(テキスト、HTMLなど)
本記事のサンプルコードでは、以下のようにdatetimeモジュールおよびcalendarモジュールをインポートしている。
import datetime
import calendar
月初(月の初日)の日付を取得
任意の日付(datetime, date)の月の初日
ある日付を指定してその月の初日の日付を返す関数は以下の通り。日にちの値をreplace()
メソッドで1
に置き換えているだけ。
日時(日付と時刻)を表すdatetime.datetime
も日付のみを表すdatetime.date
もreplace()
メソッドを持っているので、引数に指定するのはどちらでもよい。
def get_first_date(dt):
return dt.replace(day=1)
dt = datetime.datetime(2023, 8, 10, 10, 10, 10)
print(dt)
# 2023-08-10 10:10:10
print(get_first_date(dt))
# 2023-08-01 10:10:10
d = datetime.date(2023, 8, 10)
print(d)
# 2023-08-10
print(get_first_date(d))
# 2023-08-01
今の日時や今日の日付をdatetime.datetime
のnow()
メソッドやdatetime.date
のtoday()
メソッドで取得して引数とすることもできる。
- 関連記事: Pythonで現在時刻・日付・日時を取得
print(datetime.date.today())
# 2023-10-10
print(get_first_date(datetime.date.today()))
# 2023-10-01
任意の年、月の初日
年、月を指定してその月の初日の日付を返す関数はもっと単純。関数にするまでもないかもしれない。
def get_first_date2(year, month):
return datetime.date(year, month, 1)
print(get_first_date2(2023, 8))
# 2023-08-01
例はdatetime.date
を返すようにしているが、datetime.datetime
でも同様。datetime.datetime()
で時刻を省略すると00:00:00
となる。
月末(月の最終日)の日付を取得
月の日数(最終日の日)
月の最終日の日にちはその月の日数に等しい。ある月の日数はcalendar.monthrange()
で取得できる。
calendar.monthrange()
が返すのは月の初日の曜日を表す数値と日数のタプル。
- 関連記事: Pythonで月の日数・週数を取得
print(calendar.monthrange(2023, 8))
# (1, 31)
print(calendar.monthrange(2023, 8)[1])
# 31
任意の日付(datetime, date)の月の最終日
あとは初日の場合と同様。日にちの値をreplace()
メソッドで最終日に置き換えるだけ。
def get_last_date(dt):
return dt.replace(day=calendar.monthrange(dt.year, dt.month)[1])
dt = datetime.datetime(2023, 8, 10, 10, 10, 10)
print(dt)
# 2023-08-10 10:10:10
print(get_last_date(dt))
# 2023-08-31 10:10:10
d = datetime.date(2023, 8, 10)
print(d)
# 2023-08-10
print(get_last_date(d))
# 2023-08-31
print(datetime.date.today())
# 2023-10-10
print(get_last_date(datetime.date.today()))
# 2023-10-31
任意の年、月の最終日
年、月を指定する場合は以下の通り。
def get_last_date2(year, month):
return datetime.date(year, month, calendar.monthrange(year, month)[1])
print(get_last_date2(2023, 8))
# 2023-08-31
例はdatetime.date
を返すようにしているが、datetime.datetime
でも同様。
月の最終X曜日の日付を取得
最終X曜日の日にち
月の最終X曜日(最終月曜日、最終金曜日など)の日にちを算出する関数の例は以下の通り。あくまでも一例。もっとスマートな方法があるかもしれない。
第三引数dow
(day of the week: 曜日)には月曜日0
から日曜日6
までの曜日を表す数値を指定する。
def get_day_of_last_week(year, month, dow):
'''dow: Monday(0) - Sunday(6)'''
n = calendar.monthrange(year, month)[1]
l = range(n - 6, n + 1)
w = calendar.weekday(year, month, l[0])
w_l = [i % 7 for i in range(w, w + 7)]
return l[w_l.index(dow)]
結果は以下の通り。カレンダーとともに示す。
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
#
print(get_day_of_last_week(2023, 8, 0))
# 28
print(get_day_of_last_week(2023, 8, 3))
# 31
print(get_day_of_last_week(2023, 8, 4))
# 25
なお、最終X曜日は第4X曜日か第5X曜日のいずれか。第nX曜日(第2月曜日など)の日付を取得したい場合は以下の記事を参照。
以下、関数の中身を簡単に説明する。
最終日の日にちをcalendar.monthrange()
で取得して、最終週の日にちをrange()
で表現。
- 関連記事: Pythonのrange関数の使い方
year = 2023
month = 8
dow = 0
n = calendar.monthrange(year, month)[1]
print(n)
# 31
l = range(n - 6, n + 1)
print(list(l))
# [25, 26, 27, 28, 29, 30, 31]
最終週の曜日のリストを生成。
- 関連記事: Pythonリスト内包表記の使い方
w = calendar.weekday(year, month, l[0])
print(w)
# 4
w_l = [i % 7 for i in range(w, w + 7)]
print(w_l)
# [4, 5, 6, 0, 1, 2, 3]
index()
でターゲットの曜日が最終週の何番目かを取得し、さらに、その日にちを取得。
print(l[w_l.index(dow)])
# 28
任意の日付(datetime, date)の月の最終X曜日
任意の日付(datetime
, date
)から最終X曜日の日付を取得したい場合は、上で定義した関数を使って、初日や最終日と同様に処理すればよい。
def get_date_of_last_week(dt, dow):
'''dow: Monday(0) - Sunday(6)'''
return dt.replace(day=get_day_of_last_week(dt.year, dt.month, dow))
dt = datetime.datetime(2023, 8, 10, 10, 10, 10)
print(dt)
# 2023-08-10 10:10:10
print(get_date_of_last_week(dt, 0))
# 2023-08-28 10:10:10
print(get_date_of_last_week(dt, 3))
# 2023-08-31 10:10:10
d = datetime.date(2023, 8, 10)
print(d)
# 2023-08-10
print(get_date_of_last_week(d, 0))
# 2023-08-28
print(get_date_of_last_week(d, 3))
# 2023-08-31
任意の年、月の最終X曜日
年、月を指定する場合は以下の通り。
def get_date_of_last_week2(year, month, dow):
'''dow: Monday(0) - Sunday(6)'''
return datetime.date(year, month, get_day_of_last_week(year, month, dow))
print(get_date_of_last_week2(2023, 8, 0))
# 2023-08-28
例はdatetime.date
を返すようにしているが、datetime.datetime
でも同様。