使用 STRICT 解析器样式时出现 DateTimeParseException 问题
Issue with DateTimeParseException when using STRICT resolver style
我正在尝试使用以下模式解析日期字符串:yyMMdd
和 STRICT
解析器如下:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormat).withResolverStyle(ResolverStyle.STRICT);
LocalDate.parse(expiryDate, formatter);
我得到以下 DateTimeParseException
:
java.time.format.DateTimeParseException: Text '160501' could not be
parsed: Unable to obtain LocalDate from TemporalAccessor:
{YearOfEra=2016, MonthOfYear=5, DayOfMonth=1},ISO of type
java.time.format.Parsed
当我切换到默认解析样式时,即 ResolverStyle.SMART
它允许 2 月 30 日这样的日期。
有人可以帮忙吗?
严格的解析器需要一个纪元来配合 YearOfEra。将您的模式更改为使用 "u" 而不是 "y" 它将起作用,即。 "uuMMdd".
虽然 JodaStephen 很好地解释了异常的原因并给出了一个好的解决方案(使用 uu
而不是 yy
),但我提供了一些其他可能的解决方案:
- 您可能不想要的一个显而易见的方法:将解析器样式保留为
SMART
(默认值)。换句话说,要么完全省略 .withResolverStyle(ResolverStyle.STRICT)
,要么将其更改为 .withResolverStyle(ResolverStyle.SMART)
.
- 提供默认纪元。
这里是第二个选项的代码示例:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("yyMMdd")
.parseDefaulting(ChronoField.ERA, 1)
.toFormatter()
.withResolverStyle(ResolverStyle.STRICT);
String expiryDate = "160501";
LocalDate result = LocalDate.parse(expiryDate, formatter);
System.out.println(result);
输出为:
2016-05-01
与在格式模式中使用 uu
相比,最后一个解决方案可能有所不同:
- 它允许我们使用提供给我们的格式模式,我们无法控制是使用模式字母
u
还是 y
。
- 使用模式字母
y
如果字符串包含负年份,它将失败并出现异常。根据您的情况和要求,这可能是可取的或不可接受的。
编辑:parseDefaulting()
的第二个参数也可以写成 IsoEra.CE.getValue()
而不仅仅是 1
以表明我们正在指定 当前时代(CE;通常也称为 Anno Domini 或 AD)。
我正在尝试使用以下模式解析日期字符串:yyMMdd
和 STRICT
解析器如下:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormat).withResolverStyle(ResolverStyle.STRICT);
LocalDate.parse(expiryDate, formatter);
我得到以下 DateTimeParseException
:
java.time.format.DateTimeParseException: Text '160501' could not be parsed: Unable to obtain LocalDate from TemporalAccessor: {YearOfEra=2016, MonthOfYear=5, DayOfMonth=1},ISO of type java.time.format.Parsed
当我切换到默认解析样式时,即 ResolverStyle.SMART
它允许 2 月 30 日这样的日期。
有人可以帮忙吗?
严格的解析器需要一个纪元来配合 YearOfEra。将您的模式更改为使用 "u" 而不是 "y" 它将起作用,即。 "uuMMdd".
虽然 JodaStephen 很好地解释了异常的原因并给出了一个好的解决方案(使用 uu
而不是 yy
),但我提供了一些其他可能的解决方案:
- 您可能不想要的一个显而易见的方法:将解析器样式保留为
SMART
(默认值)。换句话说,要么完全省略.withResolverStyle(ResolverStyle.STRICT)
,要么将其更改为.withResolverStyle(ResolverStyle.SMART)
. - 提供默认纪元。
这里是第二个选项的代码示例:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("yyMMdd")
.parseDefaulting(ChronoField.ERA, 1)
.toFormatter()
.withResolverStyle(ResolverStyle.STRICT);
String expiryDate = "160501";
LocalDate result = LocalDate.parse(expiryDate, formatter);
System.out.println(result);
输出为:
2016-05-01
与在格式模式中使用 uu
相比,最后一个解决方案可能有所不同:
- 它允许我们使用提供给我们的格式模式,我们无法控制是使用模式字母
u
还是y
。 - 使用模式字母
y
如果字符串包含负年份,它将失败并出现异常。根据您的情况和要求,这可能是可取的或不可接受的。
编辑:parseDefaulting()
的第二个参数也可以写成 IsoEra.CE.getValue()
而不仅仅是 1
以表明我们正在指定 当前时代(CE;通常也称为 Anno Domini 或 AD)。