Instant.parse和RFC3339字符串引发java.time.format.DateTimeParseException

时间:2018-07-11 12:02:10

标签: java java-8 java-time

如果我这样做

Caused by: java.time.format.DateTimeParseException: Text '2018-06-19T23:00:00.000+01:00' could not be parsed at index 23
    at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1777)

我收到此异常:

    Instant instant = Instant.parse("2018-06-19T23:00:00.000Z");

但是,如果我这样做

echo '
{
  "a": {
    "b": [
      "c",
      "d"
    ],
    "e": [
      "f",
      "g"
    ]
  },
  "h": {
    "c": [
      "i",
      "j"
    ],
    "d": [
      "k"
    ],
    "f": [
      "l",
      "m",
      "n"
    ],
    "g": [
      "o"
    ]
  }
}' | jq '.a | keys_unsorted[]'
"b"
"e"

一切正常。

我想念什么?第一次字符串有什么问题?

3 个答案:

答案 0 :(得分:5)

原因是您的第一个Stringparse方法可接受的格式不匹配


Instant#parse(CharSequence text)的文档规定:

  

该字符串必须表示UTC中的有效时刻,并使用 DateTimeFormatter.ISO_INSTANT

进行解析

DateTimeFormatter#ISO_INSTANT的文档说明:

  

ISO即时格式化程序,用于格式化或解析UTC中的即时消息,例如“ 2011-12-03T10:15:30Z”。


要从您的字符串中获取Instant,您需要:Workable Demo

String str = "2018-01-02T18:14:59.000+01:00";
Instant instant = DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(str, Instant::from);

答案 1 :(得分:2)

您的日期字符串包含区域信息。 ISO_INSTANT(Instant ::: parse方法的默认格式)不处理此问题。改为使用

Instant instant = DateTimeFormatter.ISO_ZONED_DATE_TIME.parse(date, Instant::from);

答案 2 :(得分:1)

现在,JDK 12和更高版本可以解析它,而JDK <= 11无法解析。 DateTimeFormatter.ISO_INSTANT的Java 12 Javadoc添加了以下新句子:

解析时,将使用DateTimeFormatterBuilder.appendOffsetId()的行为来解析偏移量,并根据需要将时刻转换为UTC。

实际上,相应的JDK错误(JDK-8166138)显示该修复程序从Java 12开始可用。

例如(来自here

$ docker run --rm -it openjdk:14-jdk
Apr 27, 2020 2:28:44 PM java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.
|  Welcome to JShell -- Version 14.0.1
|  For an introduction type: /help intro

jshell> java.time.Instant.parse("2020-04-21T13:22:10.836777828-07:00");
$1 ==> 2020-04-21T20:22:10.836777828Z

jshell>