英文:
Does LocalDate.parse silently correct day number?
问题
String s = "2020 Jun 31";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy MMM dd");
LocalDate date = LocalDate.parse(s, formatter);
System.out.println(date);
Output:
2020-06-30
为什么31变成了30,却没有任何警告或异常?
<details>
<summary>英文:</summary>
String s = "2020 Jun 31";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy MMM dd");
LocalDate date = LocalDate.parse(s, formatter);
System.out.println(date);
Output:
2020-06-30
Why does 31 turn into 30 without any warnings or exceptions?
</details>
# 答案1
**得分**: 5
DateTimeFormatter有一个[ResolverStyle][1],它会影响解析器对无效日期和时间值的严格程度或宽松程度。要在这种情况下获得异常,您需要将解析器样式设置为STRICT。
您还需要在格式字符串中使用`u`(年份)而不是`y`(纪元年份)。
```java
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu MMM dd")
.withResolverStyle(ResolverStyle.STRICT);
默认的解析器类型是SMART:
使用智能解析将为每个字段执行明智的默认操作,这可能与严格相同,与宽松相同,或者是第三种行为。各个字段将以不同方式解释此行为。
例如,使用智能模式在ISO日历系统中解析年月和月日将确保月日从1到31,将任何超出最后有效月日的值转换为最后有效月日。
英文:
DateTimeFormatter has a ResolverStyle that affects how strict or lenient the parser should be with invalid date and time values. To get an exception in this case you need to set the resolver style to STRICT.
You also need to use u
(year) instead of y
(year-of-era) in the format string.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu MMM dd")
.withResolverStyle(ResolverStyle.STRICT);
The default resolver type is SMART
:
> Using smart resolution will perform the sensible default for each field, which may be the same as strict, the same as lenient, or a third behavior. Individual fields will interpret this differently.
>
> For example, resolving year-month and day-of-month in the ISO calendar system using smart mode will ensure that the day-of-month is from 1 to 31, converting any value beyond the last valid day-of-month to be the last valid day-of-month.
答案2
得分: 1
ResolverStyle
是一个枚举,提供了三种不同的处理方式:严格、智能和宽松。智能选项是默认选项。可以使用 withResolverStyle(ResolverStyle)
来设置它。以下代码会抛出异常:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.ResolverStyle;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String s = "2020 Jun 31";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("u MMM d")
.withResolverStyle(ResolverStyle.STRICT)
.localizedBy(Locale.ENGLISH);
LocalDate date = LocalDate.parse(s, formatter);
System.out.println(date);
}
}
然而,对于日期为 30
即字符串 s = "2020 Jun 30"
,它将不会抛出异常,而是正常工作,输出结果为 2020-06-30
。
更多详细信息,请查看 https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html 中的 Resolving 部分。
英文:
The ResolverStyle
is an enum that offers three different approaches: strict, smart and lenient. The smart option is the default. It can be set using withResolverStyle(ResolverStyle)
. The following code will throw an exception:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.ResolverStyle;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String s = "2020 Jun 31";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("u MMM d")
.withResolverStyle(ResolverStyle.STRICT)
.localizedBy(Locale.ENGLISH);
LocalDate date = LocalDate.parse(s, formatter);
System.out.println(date);
}
}
However, it will work without any exception for the day as 30
i.e. the output will be 2020-06-30
for String s = "2020 Jun 30"
.
Check Resolving section at https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html for more details.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论