【问题标题】:Parse String to date with timezone offset intact将字符串解析为时区偏移完整的日期
【发布时间】:2017-10-16 12:50:07
【问题描述】:

我们有一个客户以 "2017-06-14T04:00:00-08:00" 的字符串格式向我们发送日期。在使用它之前,我们需要将其转换为 JAVA Date 类型。

我们是这样解析的:

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); 
dateParsedFromString = formatter.parse("2017-06-14T04:00:00-08:00");

但是我们在这个解析之后丢失了偏移量。当我们将它转​​换回字符串时,我们看到了值:

2017-06-14T08:00:00-04:00

如何在不更改偏移量的情况下在 JAVA 中将 String 转换为 Date

【问题讨论】:

  • @MarioSantini phyton 的答案如何与 Java 中的问题重复?
  • @Jens 你是对的,对不起,我错过了链接,看看这里stackoverflow.com/questions/4203718/… 是一个 java 分析器,由于它不被接受的答案而无法被标记。
  • @Jens 不,当我打印它而不改回来时,我得到的时间不正确,为“Wed Jun 14 08:00:00 EDT 2017”。我在将其更改为字符串后给出了输出,因为它更好地解释了我的要求。

标签: java


【解决方案1】:

java.util.Date 不存储时区信息。

要保留时区,请使用ZonedDateTimeOffsetDateTime (Java 8+)。

由于您的日期字符串是ISO 8601,您甚至不需要指定日期格式。

ZonedDateTime zdt = ZonedDateTime.parse("2017-06-14T04:00:00-08:00");
System.out.println(zdt); // prints: 2017-06-14T04:00-08:00
OffsetDateTime odt = OffsetDateTime.parse("2017-06-14T04:00:00-08:00");
System.out.println(odt); // prints: 2017-06-14T04:00-08:00

对于 Java 8 之前的版本,请使用 ThreeTen-Backport

ThreeTen-Backport 将 Java SE 8 日期时间类向后移植到 Java SE 6 和 7。

【讨论】:

  • 虽然ZonedDateTime 在技术上有效,但OffsetDateTime 是合适的。时区是特定区域使用的偏移量更改的历史记录。
  • @BasilBourque 使用ZonedDateTime 是完全有效的,因为-08:00 是一个有效的时区。时区是区域偏移的超集,或者更确切地说,ZoneOffsetZoneId 的子类(限制)。
  • 那为什么我们有OffsetDateTime类呢?而且,不,-08:00不是时区。 America/Los_Angeles 是一个时区。该区域在一年中的部分时间和-07:00 在一年的另一部分时间偏移量为-08:00。偏移量随时间的变化、它们过去的历史、此时的当前偏移量以及计划在未来计划的偏移量变化,该区域的偏移量集合是一个时区。因此,您在此答案中使用 ZonedDateTime 具有误导性、混淆性,并且不适合输入数据。否则,如果您删除 ZonedDateTime,则很好回答。
  • @Andreas 感谢您的解决方案,但不幸的是我们没有使用 JAVA 8
  • @BasilBourque 仅偏移量的 ZoneId 是完全有效的 ZoneId,因此使用 ZonedDateTime 也是完全有效的。当然,您可以使用OffsetDateTime 将其限制为仅偏移量,如果您知道输入只会是这样,这可能是个好主意,但使用ZonedDateTime 是不是无效或误导性的答案,并且输入非常适合ZonedDateTime。它仍然是一个很好/有用的答案,即使其中有 ZonedDateTime
猜你喜欢
  • 2016-10-30
  • 2021-11-28
  • 1970-01-01
  • 2015-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多