DateTimeParseException:无法解析文本“2019-06-07 12:18:16”
DateTimeParseException: Text '2019-06-07 12:18:16' could not be parsed
我有以下代码将 Instant 转换为 String 然后将其转换回 I
String timestampString = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss"));
LOGGER.info("timestampString: " + timestampString);
Instant instant =
LocalDateTime.parse(timestampString,
DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss")).toInstant(ZoneOffset.UTC);
它将时间戳字符串打印为:2019-06-07 12:45:57
解析字符串失败:
java.time.format.DateTimeParseException: Text '2019-06-07 12:45:57' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {MinuteOfHour=45, HourOfAmPm=0, NanoOfSecond=0, SecondOfMinute=57, MilliOfSecond=0, MicroOfSecond=0},ISO resolved to 2019-06-07 of type java.time.format.Parsed
为什么它无法解析它,即使它与我将时间戳转换成的格式相同?
使用 HH 代替 hh
您询问的问题是您在格式模式字符串中使用小写 hh
(两次)。从 00 到 23 的小时日需要大写 HH
。hh
是从 01 到 12 的上午或下午的小时。所以出了问题的是 java.time 不知道是否 12
在您的字符串中指的是上午 12 点或下午 12 点,并且拒绝为您猜测。
如果您仔细阅读异常消息,您还会注意到它说 HourOfAmPm=0
已被解析。它没有说 HourOfDay
.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String timestampString = LocalDateTime.now().format(formatter);
System.out.println("timestampString: " + timestampString);
Instant instant = LocalDateTime.parse(timestampString, formatter)
.toInstant(ZoneOffset.UTC);
System.out.println("instant: " + instant);
当我 运行 刚才这个片段时,我得到了这个输出:
timestampString: 2019-06-08 19:22:51
instant: 2019-06-08T19:22:51Z
这是错误的!我 运行 围绕 17:22 UTC 的片段,而不是 19:22。由于丹麦仍在使用夏令时(该死的),这里的本地时间是 19:22,用于结果和 t运行 在 UTC 中设置为相同的挂钟时间,而不是相同的时刻。您应该 总是 将您想要的时区传递给 now
方法以避免此类错误。因为你想要 UTC:
String timestampString = LocalDateTime.now(ZoneOffset.UTC).format(formatter);
timestampString: 2019-06-08 17:27:57
instant: 2019-06-08T17:27:57Z
更好的是,不要使用 LocalDateTime
来存放你想暂时使用的东西。请改用 Instant
、OffsetDateTime
或 ZonedDateTime
。
有更多关于使用 hh
、HH
或 kk
格式化和解析小时值 in this question and its answers: Difference between java HH:mm and hh:mm on SimpleDateFormat 的信息。问题是问出了名的麻烦 SimpleDateFormat
,但答案对 DateTimeFormatter
也有效。
我有以下代码将 Instant 转换为 String 然后将其转换回 I
String timestampString = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss"));
LOGGER.info("timestampString: " + timestampString);
Instant instant =
LocalDateTime.parse(timestampString,
DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss")).toInstant(ZoneOffset.UTC);
它将时间戳字符串打印为:2019-06-07 12:45:57
解析字符串失败:
java.time.format.DateTimeParseException: Text '2019-06-07 12:45:57' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {MinuteOfHour=45, HourOfAmPm=0, NanoOfSecond=0, SecondOfMinute=57, MilliOfSecond=0, MicroOfSecond=0},ISO resolved to 2019-06-07 of type java.time.format.Parsed
为什么它无法解析它,即使它与我将时间戳转换成的格式相同?
使用 HH 代替 hh
您询问的问题是您在格式模式字符串中使用小写 hh
(两次)。从 00 到 23 的小时日需要大写 HH
。hh
是从 01 到 12 的上午或下午的小时。所以出了问题的是 java.time 不知道是否 12
在您的字符串中指的是上午 12 点或下午 12 点,并且拒绝为您猜测。
如果您仔细阅读异常消息,您还会注意到它说 HourOfAmPm=0
已被解析。它没有说 HourOfDay
.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String timestampString = LocalDateTime.now().format(formatter);
System.out.println("timestampString: " + timestampString);
Instant instant = LocalDateTime.parse(timestampString, formatter)
.toInstant(ZoneOffset.UTC);
System.out.println("instant: " + instant);
当我 运行 刚才这个片段时,我得到了这个输出:
timestampString: 2019-06-08 19:22:51 instant: 2019-06-08T19:22:51Z
这是错误的!我 运行 围绕 17:22 UTC 的片段,而不是 19:22。由于丹麦仍在使用夏令时(该死的),这里的本地时间是 19:22,用于结果和 t运行 在 UTC 中设置为相同的挂钟时间,而不是相同的时刻。您应该 总是 将您想要的时区传递给 now
方法以避免此类错误。因为你想要 UTC:
String timestampString = LocalDateTime.now(ZoneOffset.UTC).format(formatter);
timestampString: 2019-06-08 17:27:57 instant: 2019-06-08T17:27:57Z
更好的是,不要使用 LocalDateTime
来存放你想暂时使用的东西。请改用 Instant
、OffsetDateTime
或 ZonedDateTime
。
有更多关于使用 hh
、HH
或 kk
格式化和解析小时值 in this question and its answers: Difference between java HH:mm and hh:mm on SimpleDateFormat 的信息。问题是问出了名的麻烦 SimpleDateFormat
,但答案对 DateTimeFormatter
也有效。