JDK 8の JSR-310 java.time
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