datetimeformatter.parse()更正日期信息,而不是引发异常

quhf5bfb  于 2021-07-03  发布在  Java
关注(0)|答案(1)|浏览(349)

这个问题在这里已经有答案了

localdate.parse是否自动更正日期(2个答案)
22天前关门了。
我正在JavaSE8项目中使用JavaC15.0.1。
我有localdate的不规则输入: String fateDate = "1970-02-29" ;
对于localdate的parse(),我得到了这个异常(正确地说): LocalDate.parse(fateDate); 线程“main”java.time.format.datetimeparseexception中出现异常:无法分析文本“1970-02-29”:日期“二月29”无效,因为“1970”不是闰年
但是使用datetimeformatter会做一些更正:

final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("y-M-d");
TemporalAccessor ta = dtf.parse(fateDate);
System.out.println(ta);

收益率:
{},iso解析为1970-02-28
此行为与所有月份以及小于32天的所有值相同。因此,对于四月,您不会得到31的异常,而是一个localdate,其值为30。这看起来不像是“过早失败”的完美化身。。。
为什么会有不同的行为
在localdate.parse()和datetimeformatter.parse()中?
in-datetimeformatter for invalid days\u of \u month>31 vs.!>31?

vaj7vani

vaj7vani1#

分解样式

你自己的 DateTimeFormatter 是想变得聪明。它使用的是一种解析器样式,它确实被称为 SMART . 它是来自的格式化程序的默认值 DateTImeFormatter.ofPattern() ,但您当然可以设置为其他方式。分解器样式 SMART 像你观察到的那样做一些小的调整。另一方面,它确实知道iso日历中的一个月不能超过31天,因此仍然拒绝第32个月或更大的一天。这是一个设计决定,我不知道他们为什么要这样设计。
另一方面,arg 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年明确无误。通过这两个更改,您现在可以得到您请求的异常:
线程“main”java.time.format.datetimeparseexception中出现异常:无法分析文本“1970-02-29”:日期“二月29”无效,因为“1970”不是闰年
为了完整性,还有一种解析器样式 LENIENT 但你肯定不知道这是怎么回事。

链接

问题 uuuuyyyyDateTimeFormatter 在java?中格式化模式代码?。
meno hochschild的回答解释了为什么我们需要格式模式(在许多其他事情中) u 具有严格的解析器风格。

相关问题