(Python)日付を操作する(月末・月初・Nヶ月後など)

Pythonでプログラミングしてると、日付の操作をすることがよくあったので、その時の実装手段を色々まとめてみました。

月初を求める

月の1日を計算します。これ自体はそんなに難しくありません。Pythonの標準モジュールのdatetimeモジュールを使用します。

import datetime

d = datetime.date(2018, 5, 1)
print(d) # 2018-05-01

月末を求める

月末を計算するにはちょっとテクニックが必要です。うるう年とか30日とか31日だったりを考慮しないといけないので、計算したい月の末日がいつかを計算してくれるcalendarモジュールを利用します。
calendarモジュールのmonthrangeメソッドを使うと対象の月の日付の幅(1〜末日)をタプルで返却してくれます。

import calendar

month_range = calendar.monthrange(2018, 5)

print(month_range) # (1, 31)

# 要素を指定すれば末日だけ取得できます
print(month_range[1]) #31

# うるう年でもちゃんと末日を取得してくれます
month_range = calendar.monthrange(2020, 2)[1]

print(month_range) # 29

この、calendarモジュールのmonthrangeメソッドとdatetimeモジュールを組み合わせてあげると末日を取得することができます。

import calendar
import datetime

y = 2020
m = 2

date = datetime.date(y, m, calendar.monthrange(y, m)[1])
print(date) # 2020-02-29

Nヶ月後を求める

python-dateutilというモジュールを利用します。標準ライブラリではないので、pip installする必要があります。

$ pip install python-dateutil

python-dateutilを使うことで、日付の加算・減算処理を行うことができるようになります。

いくつか参考に記述していきます。

from dateutil.relativedelta import relativedelta

date = datetime.date(2018, 5, 1)
print(date) # 2018-05-01

# 1ヶ月後を求める
print(date + relativedelta(months=1)) # 2018-06-01

# 1ヶ月前を求める
print(date + relativedelta(months=-1)) # 2018-04-01

# 1日後を求める
print(date + relativedelta(days=1)) # 2018-05-02

# 1日前を求める
print(date + relativedelta(days=-1)) # 2018-04-30

# 1年後を求める
print(date + relativedelta(years=1)) # 2019-05-01

# 1年前を求める
print(date + relativedelta(years=-1)) # 2017-05-01

もちろん複合的な計算もできます。

from dateutil.relativedelta import relativedelta

date = datetime.date(2018, 5, 1)
print(date) # 2018-05-01

# 1年1ヶ月後の1日前を求める
print(date + relativedelta(years=1, months=1, days=-1)) # 2019-05-31

最後に

月末・月初の計算は標準ライブラリを活用すれば良いですが、日付の細かい演算はpython-dateutilモジュールを使わないとかなり処理が面倒になると思うので、積極的に使っていきたいですね。システム開発をしていると日付を操作することがよくあるので、日付の計算方法はぜひおさえておいてもらえればと思います。そうすることで、より効率的なプログラミングができるようになると思います。