首页 > 解决方案 > 如何在 Java 8 中解析字符串 YYYYMMDD_HHMMSSZ

问题描述

我需要将 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));

代码输出:

2018-05-31T13:20:01
2018-05-31T13:20:01Z

我最终需要将其保存到 SQL Server 数据库表(列类型为[datetime2](7),使用 [Spring] JDBC.

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

标签: javadatetimejava-8

解决方案


LocalDateTime可能会产生误导。它不代表您的本地日期/时间,它代表本地日期/时间。它根本没有时区信息。也就是说,它只是说例如“现在是 13:20”。它没有说13:20在哪里。由你来解释where部分。

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

使用时间戳时,最好使用ZonedDateTimeorOffsetDateTime代替。这些带有日期、时间和偏移量。

所以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

将打印:

2018-05-31T13:20:01Z

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

符合 JDBC 4.2 的驱动程序可能能够通过调用直接处理 java.time 类型setObject

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

java.sql.Timestamp.from(dateTime.toInstant());
java.util.Date.from(dateTime.toInstant());

1几乎总是存在一些在其中运行的上下文。LocalDateTime例如“ KL1302 航班明天 13:20 抵达 X 机场”。这里“明天13:20 ”的上下文是机场X的当地时间;可以通过查看X所在的时区来确定。


推荐阅读