ユーニックス総合研究所

  • home
  • archives
  • python-getsumatsu

Pythonである年月の月末日を取得する方法

  • 作成日: 2023-07-03
  • 更新日: 2023-12-24
  • カテゴリ: Python

Pythonである年月の月末日を得る

月の月末日はその月の日数の総数と同じです。
これを利用してPythonのcalendarを使って月末日を得ることができます。

import calendar  

r = calendar.monthrange(2023, 7)  
print(r)  
# (5, 31)  

print(r[1])  
# 31  

上記の結果では2023年の7月の月末日は31日ということになります。
calendar.monethrange()は以下のような構造です。

calendar.monthrange(year, month)  
    year と month で指定された月の一日の曜日と日数を返す。  

calendar.monthrange()の第1引数に年、第2引数に月を指定します。
そうするとcalendar.monthrange()は月の1日の曜日と月の日数をタプルで返します。

さきほどの出力結果で言うと

print(r)  
# (5, 31)  

というのがcalendar.monthrange()の結果です。
これのタプルの2つ目の要素に月の日数=月末日が入っていますので、これを取得するには

print(r[1])  
# 31  

という感じでインデックスを参照します。

月末日を得る自作関数を作る

先ほどのcalendar.monthrange()を利用した関数は以下が考えられます。

import calendar  

def get_last_day(year, month):  
    return calendar.monthrange(year, month)[1]  

print(get_last_day(2023, 7))  
# 31  

このような関数を定義しておけばすぐに月末日を参照できますね。

現在の日時の月末日を得る

年と月の入力を省略して自動で現在の年と月を取得し、それで月末日を得る。
ということをやりたい場合は以下のようなコードが考えられます。

import calendar  
from datetime import datetime  

def get_last_day_now():  
    d = datetime.now()  
    return calendar.monthrange(d.year, d.month)[1]  

print(get_last_day_now())  
# 31  

datetime.now()は現在の日時を取得します。
dにはyearmonthの属性が設定されていますのでこれを参照してcalendar.monthrange()を参照します。

n日後の月末日を得る

n日後の月末日を得る関数を作りたい場合は以下の実装が考えられます。

import calendar  
from datetime import datetime  
from datetime import timedelta  

def get_last_day_after_days(days):  
    d = datetime.now() + timedelta(days=days)  
    return calendar.monthrange(d.year, d.month)[1]  

# 現在の日時から31日後の月末日を得る  
print(get_last_day_after_days(31))  
# 31  

「ある日時からn日後」とうことを計算するにはdatetime.timedeltaを使います。
datetime.now()timedelta(days=days)を加算するとdays日後の日時が手に入ります。
この日時を使ってcalendar.monthrange()で月末日を計算します。

n日前の月末日を得る

n日前の月末日を得る関数を作りたい場合は先ほどの応用で以下の実装になります。

import calendar  
from datetime import datetime  
from datetime import timedelta  

def get_last_day_before_days(days):  
    d = datetime.now() - timedelta(days=days)  
    return calendar.monthrange(d.year, d.month)[1]  

# 現在の日時から31日前の月末日を得る  
print(get_last_day_before_days(31))  
# 30  

datetime.now() - timedelta(days=days)で現在日時のdays日前の日時が手に入ります。
あとはcalendar.monthrange()で月末日を得ます。

nカ月後の月末日を得る

nカ月後の月末日を得る関数を作る場合は以下の実装が考えられます。
この実装では外部ライブラリのpython-dateutilを使っていますので以下のようにpipでインストールが必要です。

$ pip install python-dateutil  
import calendar  
from datetime import datetime  
from dateutil.relativedelta import relativedelta  

def get_last_day_after_months(months):  
    d = datetime.now() + relativedelta(months=months)  
    return calendar.monthrange(d.year, d.month)[1]  

# 現在の日時から3か月後の月末日を得る  
print(get_last_day_after_months(3))  
# 31  

datetime.now() + relativedelta(months=months)で現在の日時からmonths月後の日時が手に入ります。
この日時を使ってcalendar.monthrange()で月末日を得ます。

nカ月前の月末日を得る

nカ月前の月末日を得るには先ほどの応用で、加算を減算に変えます。

import calendar  
from datetime import datetime  
from dateutil.relativedelta import relativedelta  

def get_last_day_before_months(months):  
    d = datetime.now() - relativedelta(months=months)  
    return calendar.monthrange(d.year, d.month)[1]  

# 現在の日時から3か月前の月末日を得る  
print(get_last_day_before_months(3))  
# 30  

月末日までの日時のリストを生成する

月末日までの日時のリストを得たい場合は以下のような実装が考えられます。

import calendar  
from datetime import datetime  

def get_datetimes_to_last_days(year, month):  
    days = calendar.monthrange(year, month)[1]  
    for day in range(1, days+1):  
        yield datetime(year=year, month=month, day=day)  

lis = list(get_datetimes_to_last_days(2023, 7))  
print(lis)  
# [datetime.datetime(2023, 7, 1, 0, 0), datetime.datetime(2023, 7, 2, 0, 0),  
# datetime.datetime(2023, 7, 3, 0, 0), datetime.datetime(2023, 7, 4, 0, 0),   
# datetime.datetime(2023, 7, 5, 0, 0), datetime.datetime(2023, 7, 6, 0, 0),   
# datetime.datetime(2023, 7, 7, 0, 0), datetime.datetime(2023, 7, 8, 0, 0),   
# datetime.datetime(2023, 7, 9, 0, 0), datetime.datetime(2023, 7, 10, 0, 0),   
# datetime.datetime(2023, 7, 11, 0, 0), datetime.datetime(2023, 7, 12, 0, 0),   
# datetime.datetime(2023, 7, 13, 0, 0), datetime.datetime(2023, 7, 14, 0, 0),   
# datetime.datetime(2023, 7, 15, 0, 0), datetime.datetime(2023, 7, 16, 0, 0),   
# datetime.datetime(2023, 7, 17, 0, 0), datetime.datetime(2023, 7, 18, 0, 0),   
# datetime.datetime(2023, 7, 19, 0, 0), datetime.datetime(2023, 7, 20, 0, 0),   
# datetime.datetime(2023, 7, 21, 0, 0), datetime.datetime(2023, 7, 22, 0, 0),   
# datetime.datetime(2023, 7, 23, 0, 0), datetime.datetime(2023, 7, 24, 0, 0),   
# datetime.datetime(2023, 7, 25, 0, 0), datetime.datetime(2023, 7, 26, 0, 0),   
# datetime.datetime(2023, 7, 27, 0, 0), datetime.datetime(2023, 7, 28, 0, 0),   
# datetime.datetime(2023, 7, 29, 0, 0), datetime.datetime(2023, 7, 30, 0, 0),   
# datetime.datetime(2023, 7, 31, 0, 0)]  

datetime(year=year, month=month, day=day)で指定した日時が得られます。
for文でcalendar.monthrange()で取得した月末日の分だけ回し日時を生成してyieldします。
このget_datetimes_to_last_days()yieldを使っているので返す値はジェネレーターです。
list(get_datetimes_to_last_days(2023, 7))のようにするとリストに変換できます。

ある年の全ての月の月末日を得る

ある年の全ての月の月末日を得るには以下のような関数が考えられます。

import calendar  
from datetime import datetime  

def get_all_last_days(year):  
    for month in range(1, 12+1):  
        days = calendar.monthrange(year, month)[1]  
        yield days  

lis = list(get_all_last_days(2023))  
print(lis)  
# [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]  

for文で1から12まで回してそのカウント変数をcalendar.monthrange()monthに指定します。
月末日だけじゃなくdatetimeで取得したい場合は以下の実装が考えられます。

import calendar  
from datetime import datetime  

def get_all_last_days(year):  
    for month in range(1, 12+1):  
        days = calendar.monthrange(year, month)[1]  
        yield datetime(year=year, month=month, day=days)  

lis = list(get_all_last_days(2023))  
print(lis)  
# [datetime.datetime(2023, 1, 31, 0, 0), datetime.datetime(2023, 2, 28, 0, 0),   
# datetime.datetime(2023, 3, 31, 0, 0), datetime.datetime(2023, 4, 30, 0, 0),   
# datetime.datetime(2023, 5, 31, 0, 0), datetime.datetime(2023, 6, 30, 0, 0),   
# datetime.datetime(2023, 7, 31, 0, 0), datetime.datetime(2023, 8, 31, 0, 0),   
# datetime.datetime(2023, 9, 30, 0, 0), datetime.datetime(2023, 10, 31, 0, 0),   
# datetime.datetime(2023, 11, 30, 0, 0), datetime.datetime(2023, 12, 31, 0, 0)]  

おわりに

今回はPythonで月末を得る方法を解説しました。
なにか参考になれば幸いです。

🦝 < 月末まで頑張るぞ!

🦝 < 月末締めです