JSR-310ではJava.time
JDK 8のAPI、日付に月を追加した結果を計算するためのルールは何ですか。特に、1月31日のような日付に1か月を追加するとどうなりますか?
LocalDate initial = LocalDate.of(2012, 1, 31); // 31st January 2012
LocalDate result = initial.plusMonths(1);
// what is the result?
短い答え:
この例では、結果は2月の最終日2012-02-29
になります。
説明:
「月を追加すると何日になるか」という質問は、解釈の余地があるかもしれません。これを回避するために、Java.time
APIには 明確なルール があります。無効な日付でない限り、結果は入力と同じ月の日を持ちます。無効な日付の場合、結果はその月の最後の日になります。
したがって、1月31日と1か月を足したものは、2月31日になりますが、これは無効な日付であるため、結果は2月の最後の有効な日付になります。これは、うるう年かどうかに応じて2月28日または29日です。
// normal case
2011-01-15 plus 1 month = 2011-02-15 // 15 Jan -> 15 Feb
// special rule choosing the last valid day-of-month
2011-01-31 plus 1 month = 2011-02-28 // 31 Jan -> 28 Feb (2011 is normal year)
2012-01-31 plus 1 month = 2012-02-29 // 31 Jan -> 29 Feb (2012 is leap year)
// same rule applies for months other than February
2013-03-31 plus 1 month = 2013-04-30 // 31 Mar -> 30 Apr (only 30 days in April)
同じルールが、1か月を追加する場合でも、数か月を追加する場合でも適用され、常に結果の月に基づいています。すなわち。最初に月が追加され(必要に応じて年が調整され)、その後にのみ月の日が考慮されます。減算する場合にも同じルールが適用されます。
// multiple months works on the month of the result
2013-10-31 plus 4 months = 2014-02-28 // last day of February
2013-10-31 minus 4 months = 2013-06-30 // last day of June
日付に年を加算/減算する場合にも同じルールが適用されます。年が加算された後、その月の日付の有効性がチェックされます。
// years use the same rule
2012-02-29 plus 1 year = 2013-02-28 // 29th February invalid so adjusted to 28th
ビジネスロジックで月の追加に別のルールが必要な場合は、特別なロジックをパッケージ化するTemporalAdjuster
またはTemporalAmount
を作成するのが最善の方法です。