我有以下代码抛出DateTimeParseException
:
String dateString = "Jul 20 09:32:46"
DateTimeFormatter formatter=DateTimeFormatter.ofPattern("L d HH:mm:ss");
return ZonedDateTime.parse(dateString, formatter);
根据documentation,您会发现Jul
是字符L
的示例。
但是,异常消息是:
java.time.format.DateTimeParseException:无法在索引0处解析文本“Jul”
我错过了什么?
答案 0 :(得分:6)
这里有一些问题:
MMM
而不是L
(here解释原因)。 LocalDateTime
。以下是一些替代方案:
使用时区:
String dateString = "Jul 20 2018 09:32:46+0000";
DateTimeFormatter formatter= DateTimeFormatter.ofPattern("MMM dd y H:mm:ssZ");
return ZonedDateTime.parse(dateString, formatter);
没有时区:
String dateString = "Jul 20 2018 09:32:46";
DateTimeFormatter formatter= DateTimeFormatter.ofPattern("MMM dd y H:mm:ss");
return LocalDateTime.parse(dateString, formatter);
答案 1 :(得分:2)
The answer by Juan Carlos Mendoza是正确的。我将提出我的建议作为补充:要么改进你的字符串以包括年份和时区,要么构建一个格式化程序,可以在没有它们的情况下解析当前字符串。
改善字符串
String dateString = "Jul 20 2018 09:32:46 America/Argentina/La_Rioja";
DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("LLL d uuuu HH:mm:ss VV", Locale.ROOT);
System.out.println(ZonedDateTime.parse(dateString, formatter));
打印
2018-07-20T09:32:46-03:00[America/Argentina/La_Rioja]
同样的格式化程序也会将Jul 20 2018 09:32:46 -08:30
解析为2018-07-20T09:32:46-08:30的ZonedDateTime
。
第一个潜在的问题是语言环境。如果“Jul”是英语,则提供说英语的语言环境,或者在使用7月份被称为其他语言的语言的计算机上解析可能会失败。我建议您始终使用格式化程序指定区域设置。即使你最终选择Locale.getDefault()
。它仍会告诉读者(和你自己)你做出了有意识的选择。
下一页the documentation表示M
和L
都可以将月份作为数字/文字,并提供示例7; 07; 7月;七月; J.所以这一行显然是相关的:“数字/文字:如果模式字母的数量是3或更大,请使用上面的文本规则。否则使用上面的数字规则。“由于”Jul“是文本,你需要3个或更多的模式字母。 “少于4个模式字母将使用缩写形式。”“Jul”很短,所以我们需要三个字母。
无论我在格式模式字符串中使用MMM
还是LLL
,上面的代码都适用于Java 9.0.4。在jdk1.8.0_131中,它与MMM
一起使用,但有时会失败LLL
,这可能是一个错误(在Mac上测试过)。请参阅Juan Carlos Mendoza,了解M
和L
之间的预期差异。
构建一个有效的格式化程序
String dateString = "Jul 20 09:32:46";
ZoneId zone = ZoneId.of("America/Argentina/La_Rioja");
DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendPattern("LLL d HH:mm:ss")
.parseDefaulting(ChronoField.YEAR, Year.now(zone).getValue())
.toFormatter(Locale.ROOT)
.withZone(zone);
System.out.println(ZonedDateTime.parse(dateString, formatter));
这会将您问题中的字符串解析为2018-07-20T09:32:46-03:00[America/Argentina/La_Rioja]
。如果没有与我随机选择的时区一致,请替换您想要的默认时区。如果您不想要当年,也可以替换您想要的年份。
我的Java 8再次需要MMM
而不是LLL
。