【问题标题】:DateTimeParseException: Text '2019-06-07 12:18:16' could not be parsedDateTimeParseException:无法解析文本“2019-06-07 12:18:16”
【发布时间】:2019-06-07 19:49:52
【问题描述】:

我有以下代码将 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 而不是hhhh 是一天中的 12 小时 小时;你想要一天中的 24 小时。
  • 我确实想知道 为什么 你将它转换为字符串并返回,请注意 - 请注意 LocalDateTime.now() 使用系统时区,而你当时声称它是UTC。如果您可以为您想要实现的目标提供更多背景信息,我们可能会在解析之外为您提供更多帮助。
  • LocalDateTime 是跟踪时刻的错误类,如其 Javadoc 中所述。请改用InstantOffsetDateTimeZonedDateTime

标签: java java-time datetime-parsing


【解决方案1】:

使用 HH 代替 hh

您要问的问题是您在格式模式字符串中使用了小写hh(两次)。您需要大写 HH 表示从 00 到 23 的小时日。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);

当我刚才运行这个 sn-p 时,我得到了这个输出:

timestampString: 2019-06-08 19:22:51
instant: 2019-06-08T19:22:51Z

这是错误!我在世界标准时间 17:22 左右运行了 sn-p,而不是 19:22。由于丹麦仍在使用夏令时(该死),因此这里的当地时间是 19:22,用于结果并转换为 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 来保存您想在某个时刻使用的东西。请改用InstantOffsetDateTimeZonedDateTime

有更多关于使用hhHHkk 格式化和解析小时值in this question and its answers: Difference between java HH:mm and hh:mm on SimpleDateFormat 的信息。问题是询问臭名昭著的麻烦SimpleDateFormat,但答案对DateTimeFormatter 也有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-01
    • 1970-01-01
    • 2017-09-29
    • 2022-07-01
    • 2022-01-05
    • 2019-02-15
    • 2019-07-10
    相关资源
    最近更新 更多