如何将ISO 8601日期时间字符串转换为java.util.LocalDateTime?

dha*_*aks 3 java datetime java-8

我正在从Wikidata读取数据。它们代表使用ISO 8601规范的时间点属性P585。但是,相同的生物带有+。

如果我使用的是Joda,那么将String转换为joda dateTime将会非常简单。

new DateTime(dateTime, DateTimeZone.UTC);
Run Code Online (Sandbox Code Playgroud)

但是,当我这样做时,LocalDateTime.parse("+2017-02-26T00:00:00Z")我收到一条错误消息,提示无法解析索引0处的字符。在Java 8中是否有此原因。Joda可以很轻松地做到这一点而没有任何错误。

我也试过,LocalDateTime.parse("+2017-02-26T00:00:00Z", DateTimeFormatter.ISO_DATE_TIME)但徒劳。

我们如何绕过加号而不必通过字符串操作将其删除?

Stv*_*dll 6

Java的DateTimeFormatter类可能会有所帮助。以下是一些我认为可以解决您的问题的示例代码(或至少为您提供了一些思考):

class DateTimeTester {
  ---
  public static void main(String[] args) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("+yyyy-MM-dd'T'HH:mm:ss'Z'")
        .withZone(ZoneId.of("UTC"));
    LocalDateTime date = LocalDateTime.parse("+2017-02-26T01:02:03Z", formatter);
    System.out.println(date);
  }
}
Run Code Online (Sandbox Code Playgroud)

参考部分叫的格式和分析模式的javadoc DateTimeFormatter约传递给格式字符串的详细信息DateTimeFormatter.ofPattern()

注意事项:

Wikidata的可用数据类型列表说明了该time数据类型:

“时间点的显式值,表示为类似于 ISO 8601 的时间戳,例如+ 2013-01-01T00:00:00Z。年份始终经过签名并填充为4到16位之间的数字。”

因此,Wikidata的time数据类型仅类似于 ISO 8601。

如果您的代码需要处理负数年(在0年之前),则需要相应地调整我建议的解决方案。

  • 我认为你可以用 DateTimeFormatter.ISO_LOCAL_DATE_TIME 替换这些格式字符串 (3认同)

Arv*_*ash 5

不幸的是,所接受的答案是错误的,原因有以下三个:

  1. 给定的日期时间字符串+2017-02-26T00:00:00Z不代表LocalDateTime. 它代表一个OffsetDateTime.
  2. 它使用+带有模式的符号,这意味着该模式将无法解析具有负年份的日期时间。
  3. 'Z'不等于Z.

DateTimeFormatter您可以使用DateTimeFormatterBuilder如下所示创建所需的:

class Main {
    public static void main(String[] args) {
        DateTimeFormatter parser = new DateTimeFormatterBuilder()
                .appendValue(ChronoField.YEAR, 4, 4, SignStyle.ALWAYS)
                .appendPattern("-MM-dd'T'HH:mm:ssXXX")
                .toFormatter(Locale.ENGLISH);
        OffsetDateTime odt = OffsetDateTime.parse("+2017-02-26T00:00:00Z", parser);
        System.out.println(odt);

        // If you want a LocalDateTime, you can get it from `odt`
        LocalDateTime ldt = odt.toLocalDateTime();
        System.out.println(ldt);
    }
}
Run Code Online (Sandbox Code Playgroud)

输出

2017-02-26T00:00Z
2017-02-26T00:00
Run Code Online (Sandbox Code Playgroud)

ONLINE DEMO

从Trail: Date Time中了解有关现代日期时间 API 的更多信息。

  • 接受答案的有效点 (2认同)