始めに
各月の第2営業日に処理したいバッチ処理がありました。
PythonのpandasのCustomBusinessMonthBegin
で営業日を計算できそうだったので、各月の営業日を求める方法を記載します。
環境
- Python
- 3.12.3
- holidays
- 0.50
- pandas
- 2.2.2
実装
祝日と営業日について
前回の記事である程度解説しているので、前回の記事を参考にしてください。
月最初の営業日を求める
CustomBusinessMonthBegin
で月の最初の営業日を求められます。今回の記事ではエイリアスのCBMonthBegin
を使用します。
月の最初の営業日 + 求めたい営業日 - 1
で計算できます。今回は第2営業日を求めたいので、2 - 1 = +1します。
# 営業日のインスタンスを生成する b_day = CDay(n=2 - 1, weekmask="Mon Tue Wed Thu Fri", holidays=jpholidays) # 月初営業日のインスタンスを生成する。 b_month_begin = CBMonthBegin(weekmask=b_day.weekmask, holidays=b_day.holidays) # 月初日のインスタンスを生成する base = pd.Timestamp(2024, 6, 1) # 月初営業日まで日付を移動させる b_base = b_month_begin.rollforward(base) # 月初日営業日 + 加算する営業日 result = b_base + b_day
最終コード
最終的には次のようなコードで目的の月の第2営業日を求められます。
@pytest.mark.parametrize( "year, month, expected", [ (2024, 1, "2024-01-03"), (2024, 2, "2024-02-02"), (2024, 6, "2024-06-04"), ] ) def test_second_business_date(year, month, expected): """ 第二営業日 を求める """ jpholidays = holidays.Japan(years=[year]) add_b_day = 2 - 1 b_day = CDay(n=add_b_day, weekmask="Mon Tue Wed Thu Fri", holidays=jpholidays) b_month_begin = CBMonthBegin(weekmask=b_day.weekmask, holidays=b_day.holidays) base = pd.Timestamp(year, month, 1) b_base = b_month_begin.rollforward(base) assert b_base + b_day == pd.Timestamp(expected)
ソースコード
終わりに
CBMonthBegin
の扱い方が分からなくて長時間ハマりました。
正直、本当にやりたいことはバッチをキックする側のスケジューラを設定することですが、とりあえず判別できるようになったので良しとします。