Java JodaTime - 29.02.2024 - dayOfMonth 的值 29 必须在 [1,28] 范围内 - 闰年

qum*_*uma 3 java date jodatime leap-year

我在我的应用程序中使用此代码:

final DateTime selectedDate = new DateTime().withMonthOfYear(month).withDayOfMonth(day).withYear(year);
Run Code Online (Sandbox Code Playgroud)

其中month= 2, day= 29, year= 2024

我得到这个例外:

Value 29 for dayOfMonth must be in the range [1,28]
Run Code Online (Sandbox Code Playgroud)

但2024年是闰年。有人对此有解决方案吗?

Daw*_*ica 6

尽管表达式的最终值似乎是有效日期,但您已按照需要一路评估无效日期的顺序对其进行评估。

你写了

final DateTime selectedDate = 
    new DateTime().withMonthOfYear(month).withDayOfMonth(day).withYear(year);
Run Code Online (Sandbox Code Playgroud)

从左到右评估。因此它相当于

DateTime result1 = new DateTime().withMonthOfYear(month);
DateTime result2 = result1.withDayOfMonth(day);
final DateTime selectedDate = result2.withYear(year);
Run Code Online (Sandbox Code Playgroud)

现在,假设我今天(2023 年 3 月 20 日)按照month = 2, day = 29, year = 2024您指定的方式运行此操作。然后我有

DateTime result1 = 20 February 2023 // all good so far
DateTime result2 = 29 February 2023 // whoops!
Run Code Online (Sandbox Code Playgroud)

这就是抛出异常的地方。我们从未将年份定为 2024 年。

重新排列代码以便withYear首先调用可以解决此问题,因为所有中间结果都是有效日期。

final DateTime selectedDate = 
    new DateTime().withYear(year).withMonthOfYear(month).withDayOfMonth(day);
Run Code Online (Sandbox Code Playgroud)

更好的主意是奥莱的主意

final DateTime selectedDate = new DateTime().withDate(year, month, day);
Run Code Online (Sandbox Code Playgroud)

它在一次调用中设置所有三个字段,因此您无需担心中间结果。

但最好的想法是使用java.time包中的类,而不是 Joda。Joda 已经过时近 10 年了。

import java.time.LocalDate;

// ...

final LocalDate selectedDate = LocalDate.of(year, month, day);
Run Code Online (Sandbox Code Playgroud)