- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
为什么这个测试通过了,而月份值却明显无效(13)?
@Test
public void test() {
String format = "uuuuMM";
String value = "201713";
DateTimeFormatter.ofPattern(format).withResolverStyle(ResolverStyle.STRICT)
.parse(value);
}
使用临时查询时,会引发预期的 DateTimeParseException
:
DateTimeFormatter.ofPattern(format).withResolverStyle(ResolverStyle.STRICT)
.parse(value, YearMonth::from);
未指定 TemporalQuery
时会发生什么?
编辑:13 值似乎是一个特殊的值,正如我从 ΦXocę 웃 Пepeúpa ツ 的回答中了解到的那样(参见 Undecimber )。
但即使使用其他值(例如 50)也不会引发异常:
@Test
public void test() {
String format = "uuuuMM";
String value = "201750";
DateTimeFormatter.ofPattern(format).withResolverStyle(ResolverStyle.STRICT)
.parse(value);
}
最佳答案
我在这里进行了一些调试,发现解析过程的一部分是根据格式化程序的时间顺序检查字段。
当您创建DateTimeFormatter
时,by default它使用 IsoChronology
,用于解析日期字段。在此解决阶段,the method java.time.chrono.AbstractChronology::resolveDate
被调用。
如果你看source ,您将看到以下逻辑:
if (fieldValues.containsKey(YEAR)) {
if (fieldValues.containsKey(MONTH_OF_YEAR)) {
if (fieldValues.containsKey(DAY_OF_MONTH)) {
return resolveYMD(fieldValues, resolverStyle);
}
....
return null;
由于输入仅包含年和月字段,因此fieldValues.containsKey(DAY_OF_MONTH)
返回false
,该方法返回 null
并且没有进行其他检查,如 Parsed
class 中所示。 .
因此,在没有 TemporalQuery
的情况下解析 201750
或 201713
时,由于上述逻辑,不会进行额外的检查,并且 parse
方法返回一个 java.time.format.Parsed
对象,如以下代码所示:
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("uuuuMM").withResolverStyle(ResolverStyle.STRICT);
TemporalAccessor parsed = fmt.parse("201750");
System.out.println(parsed.getClass());
System.out.println(parsed);
输出为:
class java.time.format.Parsed
{Year=2017, MonthOfYear=50},ISO
请注意,返回对象的类型是java.time.format.Parsed
,打印它会显示已解析的字段(年和月)。
当您使用 TemporalQuery
调用 parse
时,Parsed
对象会传递给查询,并且它的字段会被验证(当然这取决于查询,但 API 内置查询始终有效)。
对于 YearMonth::from
,它使用相应的 ChronoField
( MONTH_OF_YEAR 和 YEAR )检查年份和月份是否有效。月份字段仅接受值 from 1 to 12 .
这就是为什么仅调用 parse(value)
不会引发异常,但使用 TemporalQuery
调用则会引发异常。
当所有日期字段(年、月和日)都存在时,检查上面的逻辑:
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("uuuuMMdd").withResolverStyle(ResolverStyle.STRICT);
fmt.parse("20175010");
这会抛出:
Exception in thread "main" java.time.format.DateTimeParseException: Text '20175010' could not be parsed: Invalid value for MonthOfYear (valid values 1 - 12): 50
由于所有日期字段都存在,fieldValues.containsKey(DAY_OF_MONTH)
返回 true
,现在它检查它是否是有效日期(使用 resolveYMD
method )。
关于java-8 - 为什么 Java 8 DateTimeFormatter 在 ResolverStyle.STRICT 模式下允许不正确的月份值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45839399/
为什么这个测试通过了,而月份值却明显无效(13)? @Test public void test() { String format = "uuuuMM"; String value
我正在使用: @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) @JsonFormat( pattern = "MM-dd-yyyy" ) private
我是一名优秀的程序员,十分优秀!