java - DateTimeFormatter.parse() 更正日期信息而不是抛出异常
问题描述
我在 Java SE8 项目中使用 javac 15.0.1。
我对 LocalDate 有不规则的输入:
String fateDate = "1970-02-29"
;
使用 LocalDate 的 parse() 我得到这个异常(正确):
LocalDate.parse(fateDate);
线程“主”java.time.format.DateTimeParseException 中的异常:无法解析文本“1970-02-29”:日期“2 月 29 日”无效,因为“1970”不是闰年
但是使用 DateTimeFormatter 会进行某种更正:
final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("y-M-d");
TemporalAccessor ta = dtf.parse(fateDate);
System.out.println(ta);
产生于:
{},ISO 解析为 1970-02-28
此行为对于所有月份和 day<32 的所有值都是相同的。因此,对于四月,您不会得到 31 的异常,而是将 LocalDate 以 30 作为一天的值。这看起来不像是“早早失败”的完美化身......
为什么会有不同的行为
- 在 LocalDate.parse() 与 DateTimeFormatter.parse() 中?
- 在 DateTimeFormatter 中为无效的 days_of_month >31 与!>31?
解决方案
解析器样式
你自己DateTimeFormatter
正在努力变得聪明。它使用了一种确实被称为SMART
. 这是来自 的格式化程序的默认设置DateTImeFormatter.ofPattern()
,但您当然可以设置它。解析器样式SMART
会像您观察到的那样进行小的调整。另一方面,它确实知道 ISO 日历中的一个月不能超过 31 天,因此仍然拒绝第 32 个月或更大的日期。这是一个设计决定,我不知道他们为什么要这样设计。
另一方面,单参数使用具有解析器样式LocalDate.parse()
的内置。它拒绝所有在预测公历中无效的日期。DateTimeFormatter.ISO_LOCAL_DATE
STRICT
正如我所说,您可以在格式化程序上设置解析器样式:
String fateDate = "1970-02-29";
final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("u-M-d")
.withResolverStyle(ResolverStyle.STRICT);
TemporalAccessor ta = dtf.parse(fateDate );
System.out.println(ta);
编辑:我需要进行另一项更改。因为使用严格的解析器样式,格式化程序根本拒绝将时代的年份、月份和月份的日期解析为日期。您使用的格式字母y
表示年代,严格来说Java不知道1970是1970 BCE(BC)还是1970 CE(AD),因此无法解析。使用智能解析器样式,它将默认为普通时代(我们的时代);不严格。相反,我使用u
的是有符号年份,这使得 1970 年明确。通过这两项更改,您现在得到了您要求的异常:
线程“主”java.time.format.DateTimeParseException 中的异常:无法解析文本“1970-02-29”:日期“2 月 29 日”无效,因为“1970”不是闰年
为了完整起见,还有一种解析器样式LENIENT
,但您当然不适合您的情况。
链接
- 问题
uuuu
与yyyy
在DateTimeFormatter
Java 中格式化模式代码?.- Meno Hochschild 的回答解释了(在许多其他事情中)为什么我们需要
u
具有严格解析器风格的格式模式。
- Meno Hochschild 的回答解释了(在许多其他事情中)为什么我们需要
推荐阅读
- python - 查找错误的常见子索引值?
- magento - Magento 2 Admin 和前端显示错误“utils”
- php - 我只想通过编写雄辩的 $query 范围函数来获取第一个表的数据
- graph - 未调用阿波罗服务器突变解析器
- python - 在派生字段上查询 Django
- javascript - 为什么我不能将此代码部署到 firebase 函数?我不明白错误
- raster - 计算栅格中的波段数
- asp.net-mvc - Intellisense 不建议在 VS 2019 中用于旧 MVC5 项目
- r - 1:n[j != 0] 中的代码错误:NA/NaN 参数
- reactjs - 在父组件中使用 fetch 传递给子组件