日付の加減算
「30 日後」を自分で数えると、月末で必ず間違える
貸出日から返却期限を出す、契約日から更新日を出す。どれも「この日から N 日後」を求めるだけの計算に見えます。ところが日にちを足して 31 を超えたら月を 1 つ進めて、その月が 30 日までなら差を調整して、2 月なら年を見てうるう年かどうかを判定して、と条件が雪だるま式に増えていきます。
LocalDate はこれを丸ごと引き受けてくれます。plusDays に日数を渡すだけです。
Java
import java.time.LocalDate;
public class Demo {
public static void main(String[] args) {
LocalDate borrowed = LocalDate.of(2026, 1, 25);
LocalDate dueDate = borrowed.plusDays(14);
System.out.println(dueDate); // 2026-02-08
}
}1 月 25 日 の 14 日後が 2 月 8 日 になりました。月をまたぐ処理も、その月が何日まであるかの判定も、こちらでは書いていません。plusWeeks plusMonths plusYears も同じ形で使えます。
過去に戻したいときに、引き算を書く必要はない
戻す方向は minusDays を使うか、plusDays に負の数を渡すかのどちらでもかまいません。結果は同じです。
Java
LocalDate borrowed = LocalDate.of(2026, 1, 25);
System.out.println(borrowed.minusDays(7)); // 2026-01-18
System.out.println(borrowed.plusDays(-7)); // 2026-01-18読み手にとっては、過去なら minusDays、未来なら plusDays と書き分けるほうが分かりやすくなります。ただし、画面から +10 や -7 のような符号つきの数値がそのまま渡ってくる場合は、plusDays 1 本で受けたほうが if による場合分けを増やさずに済みます。
1 月 31 日 の 1 か月後は 2 月 31 日 にならない
日数の足し算に比べて、月の足し算には気をつけるところがあります。存在しない日付になってしまうときは、その月の末日に丸められます。
Java
System.out.println(LocalDate.of(2026, 1, 31).plusMonths(1)); // 2026-02-28
System.out.println(LocalDate.of(2024, 1, 31).plusMonths(1)); // 2024-02-29
System.out.println(LocalDate.of(2024, 2, 28).plusDays(1)); // 2024-02-29「毎月 31 日に課金する」という仕様をそのまま plusMonths で回すと、2 月をまたいだ時点で 28 日にずれ、そこから先はずっと 28 日のままになります。丸めが起きたかどうかを気にする処理では、結果の getDayOfMonth() を確認するか、日数で動かす設計に切り替えてください。
月初を求めたいだけなら
withDayOfMonth(1)が使えます。plusやminusが「ずらす」のに対して、withから始まるメソッドは「その部分だけ差し替える」ものです。
やってみよう
Solution.addDays(int year, int month, int day, int n) を完成させます。
- ファイルの先頭に
import java.time.LocalDate;を書く - 受け取った年・月・日から
LocalDateを作る - そこから
n日ずらした日付を求め、ISO 形式の文字列にしてreturnする
addDays(2024, 1, 31, 1) は "2024-02-01"、addDays(2026, 5, 19, -19) は "2026-04-30" です。n が負の場合も同じ 1 本の呼び出しで通るので、符号による場合分けは書かないでください。
要件
- ファイル先頭で
import java.time.LocalDate;を書くこと LocalDate.of(year, month, day)でLocalDateを生成し、plusDays(n)でn日後のLocalDateを求めること- 求めた
LocalDateのtoString()の結果をreturnすること (yyyy-MM-dd形式の文字列になる)
入出力例
addDays(2026, 5, 19, 10) → "2026-05-29"
addDays(2024, 1, 1, 30) → "2024-01-31"
addDays(2024, 1, 31, 1) → "2024-02-01"
addDays(2026, 5, 19, -19) → "2026-04-30"
addDays(2024, 2, 28, 1) → "2024-02-29"