【问题标题】:Parse date-time from String with offset with one-digit hours从字符串中解析日期时间,偏移量为一位数小时
【发布时间】:2018-05-15 07:36:08
【问题描述】:

我需要在 Java 中解析日期。我有字符串值2018-05-15 09:32:51.550082 +3:00,我需要将其解析为日期时间。我试图解析到 ZonedDateTime,但在索引 10 处出现错误。尝试使用 DateTimeFormatter 解析器 'yyyy-MM-dd HH:mm:ss.SSSSSS Z' 解析并在索引 26 处出错。显然我的无法解析 +3:00 的 UTC 偏移量。我该怎么做?

【问题讨论】:

  • 什么语言?
  • ...或在其来源处获取正确的格式
  • 这显然是首选方式。我不明白什么时候程序不只是简单地遵守 ISO 8601 的时间格式。
  • @OleV.V.好主意,但遗憾的是,该模式仅允许 H,它必须是 HH,否则您会遇到 IllegalArgumentException
  • @Ben 你说得对:它在 Java 8 中不起作用,但在 Java 9 和 10 中起作用。

标签: java date parsing timezone-offset datetime-parsing


【解决方案1】:

Java 9 及更高版本允许:

    String dateTimeString = "2018-05-15 09:32:51.550082 +3:00";
    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .appendPattern("uuuu-MM-dd HH:mm:ss.SSSSSS ")
            .appendOffset("+H:MM:ss", "+0:00")
            .toFormatter();
    OffsetDateTime dateTime = OffsetDateTime.parse(dateTimeString, formatter);
    System.out.println(dateTime);

输出:

2018-05-15T09:32:51.550082+03:00

对于 Java 8 或 ThreeTen Backport,您可能需要在解析之前准备好日期时间字符串:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSSSSS XXX");
    dateTimeString 
            = dateTimeString.replaceFirst("([+-])(\\d(?::\\d\\d){0,2})$", "$10$2");

其余的和以前一样,并给出相同的结果。 replaceFirst 调用在 +3:00 之间插入一个 0,但前提是小时数仅为一位数。正则表达式难以阅读,因此您会更喜欢 Java 9 解决方案。

正如在 cmets 中已经讨论的,困难的部分是+3:00 的偏移量。 Java 的内置格式化程序和可用于指定自己的格式的格式模式字母都需要在偏移量中使用两位数的小时数。我使用的DateTimeFormatterBuilder.appendOffset 方法允许指定有限数量的格式; Java 8 中的 9 种不同格式;在 Java 9 中为 22。

【讨论】:

  • 谢谢。无法在 Java 9 上检查它,但在 Java 8 上一切正常。真的很酷的答案
【解决方案2】:

来自 MadProgrammer 的评论真的很有帮助。谢啦。 起初我在时区的 3 之前添加 0 并且我的字符串变为 '2018-05-15 09:32:51.550082 +03:00' 然后我使用 DateTimeFormatter 'yyyy-MM-dd HH:mm:ss.n z' 和现在一切正常。谢谢大家

【讨论】:

  • 这给了我 2018-05-15T09:32:51.000550082+03:00。第二个小数点在右边太远的三个位置。否则很好。无论如何,感谢您分享您的解决方案。
猜你喜欢
  • 2021-11-28
  • 2016-10-29
  • 1970-01-01
  • 2017-10-16
  • 2015-04-29
  • 2015-02-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多