如何在Java 8中解析字符串YYYYMMDD_HHMMSSZ

Web*_*ser 1 java datetime java-8

我需要将UTC日期和时间字符串(例如20180531_132001Z)解析为Java 8日期和时间对象.如何使用Java 8的新日期和时间库进行此操作?我看到的大多数示例都是针对LocalDateTime的,如下所示:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss'Z'");
    LocalDateTime localDateTime = LocalDateTime.parse("20180531_132001Z", formatter);
    System.out.println(localDateTime);
    System.out.println(localDateTime.atOffset(ZoneOffset.UTC));
Run Code Online (Sandbox Code Playgroud)

代码输出:

2018-05-31T13:20:01
2018-05-31T13:20:01Z
Run Code Online (Sandbox Code Playgroud)
  • 这是当地时间还是UTC时间?我正在解析的字符串值是基于UTC的,所以我想知道在持久化到数据库之前是否需要做进一步的操作.
  • 如果是前者,我该如何将其转换为UTC日期和时间?

我最终需要将它持久化到SQL Server数据库表(列类型是[datetime2](7),使用[Spring] JDBC.

更新:根据评论和答案,我认为我的问题没有经过深思熟虑.换句话说,如果我得到一个输入字符串并且我解析它而不考虑任何区域或偏移量,我将得到一个LocalDateTime对象.如何获取该对象并将封装的值转换为UTC日期和时间?

rus*_*tyx 9

LocalDateTime可能会产生误导.这并不代表你的本地日期/时间,它代表了一个本地的日期/时间.它根本没有时区信息.也就是说,它只是说"它是13:20".它没有说13:20 在哪里.由你来解释where部分.

由于这LocalDateTime对于携带时间戳通常不是很有用,因此它仅适用于时区依赖于某些上下文的情况.1

使用时间戳时,最好使用ZonedDateTimeOffsetDateTime替代.这些包含日期,时间和偏移量.

因此,localDateTime.atOffset(ZoneOffset.UTC)实际上将OffsetDateTime通过解释localDateTime为UTC时间来返回实例.

有人可能会争辩说,你可以通过首先解析时区信息来避免解释部分(即使它总是如此Z):

    String example = "20180531_132001Z";
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd_HHmmssX");
    OffsetDateTime dateTime = OffsetDateTime.parse(example, formatter);
    System.out.println(dateTime); // look ma, no hardcoded UTC
Run Code Online (Sandbox Code Playgroud)

将打印:

2018-05-31T13:20:01Z
Run Code Online (Sandbox Code Playgroud)

附加值是您的代码自动支持时区(例如"20180531_132001+05").

JDBC 4.2兼容驱动程序可以通过调用直接寻址java.time类型setObject.

对于较旧的JDBC驱动程序,您可以转换dateTimejava.sql.Timestampjava.util.Date:

java.sql.Timestamp.from(dateTime.toInstant());
java.util.Date.from(dateTime.toInstant());
Run Code Online (Sandbox Code Playgroud)

1几乎总有一些背景在其中LocalDateTime运作.例如" 航班KL1302明天13:20到达机场X ".这里" 明天13:20 " 的背景是X机场的当地时间; 它可以通过查找X的时区来确定.