解説
1か月後と30日後は同じ?AIへ日程を頼む前に月末のルールを決めよう
1月31日の1か月後は何日?存在しない日を月末へ収める架空ルールをPythonで検算し、日数の加算・繰り返し・月末固定を分ける。

AIに「1月31日の1か月後へ予定を移して」と頼むとき、何月何日になる想定かな。毎月の同じ日を目指すことと、30日を足すことは別だよ。さらに、翌月に31日がない場合の決め方も必要になる。
この記事では、日付の一覧を作る前に月単位のルールを固定する。題材は架空の日程。契約の満了日や請求日を判定する仕組みではなく、Python 3の標準ライブラリで小さく検算する練習だよ。
日数と、暦の月を分ける
2026年1月31日へ30日を足すと3月2日。一方、「翌月の同じ日を目指し、その日がなければ翌月の末日」と決めれば2月28日になる。どちらか一方だけが、すべての場面で正しいわけではないんだ。
Pythonのtimedeltaは日・秒などの時間差を表し、月という引数はない。月の日数は一定ではないため、timedelta(days=30)を「1か月」と読み替えないようにしよう。
| 元の日 | 今回決めた1か月後 | 30日後 |
|---|---|---|
| 2026-01-31 | 2026-02-28 | 2026-03-02 |
| 2028-01-31 | 2028-02-29 | 2028-03-01 |
うるう年の2028年は2月が29日まで。日付の文字を置き換えるだけでは、存在しない2月31日を作ってしまうね。
今回のルールを関数にする
ここでは「移動先の年月を決め、元の日と移動先の末日の小さい方を使う」と定める。これは今回の検算用ルールで、Pythonやすべてのカレンダーサービスが自動で同じ処理をするという意味ではないよ。
from datetime import date, timedelta
from calendar import monthrange
def add_months_clamped(day, months):
year, zero_based_month = divmod(
day.year * 12 + day.month - 1 + months, 12
)
month = zero_based_month + 1
last_day = monthrange(year, month)[1]
return date(year, month, min(day.day, last_day))
start = date(2026, 1, 31)
print(add_months_clamped(start, 1))
print(start + timedelta(days=30))
表示は順に2026-02-28、2026-03-02。monthrangeの二つ目の返り値は、その年月の日数だよ。時刻やタイムゾーンのないdateを使っているので、「現地時間で何時に実行するか」はこの計算の対象外になる。
一度に2か月と、1か月を2回は違う
月末へ収めると、元が31日だった情報は結果の日付から失われる。上のコードに続けて、次も実行してみよう。
print(add_months_clamped(start, 2))
print(add_months_clamped(add_months_clamped(start, 1), 1))
最初は2026-03-31、次は2026-03-28。後者は一度2月28日へ移ってから、その28日を基準にしているんだ。繰り返し予定を31日へ戻したいなら、毎回の結果へ足すのではなく、最初の日付と何か月後かを保持する方法を考えよう。
「常に月末」も別ルール。4月30日の翌月をこの関数で計算すると5月30日であり、5月31日にはならない。毎月最終日という指定なら、移動先の末日を直接選ぶ必要があるね。逆方向へ戻す操作でも、月末へ収めた後に元の日を必ず復元できるわけではないよ。
AIへの依頼に、判断条件を残す
架空の日付一覧を整理してください。
「nか月後」は元の年月からnか月先を求めます。
同じ日が存在しなければ、その月の末日を使います。
各回は最初の日付を基準にし、直前の結果へ加算しません。
元の日付・n・結果・適用したルールを表に残してください。
不明な契約上の期限や休日調整は推測しないでください。
これは依頼文の例であり、AIを実行して得た結果ではないよ。結果は1月31日、うるう年、年またぎ、1か月後と2か月後を検算しよう。今回のコードはdatetime.dateが扱う年の範囲内で使い、入力の形式検査や契約条件の判定は別に行う。
編集部では2026年11月1日に公式資料を確認し、掲載コードと月末・うるう年・年またぎの例をPython 3.12.14で検算した。実アカウントの予定や契約は変更していない。営業日の起算日と休日、日付形式のあいまいさも別々に確認してみよう。

みんなのコメント 0
感想や、試してみたことを聞かせてね。コメント・返信は承認後に公開されます。
最初のコメントをどうぞ。