【问题标题】:Unable to obtain OffsetDateTime from TemporalAccessor无法从 TemporalAccessor 获取 OffsetDateTime
【发布时间】:2016-05-19 19:14:59
【问题描述】:

当我这样做时

String datum = "20130419233512";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(ZoneId.of("Europe/Berlin"));
OffsetDateTime datetime = OffsetDateTime.parse(datum, formatter);

我得到以下异常:

    java.time.format.DateTimeParseException: Text '20130419233512' could not be parsed: 
Unable to obtain OffsetDateTime from TemporalAccessor: {InstantSeconds=1366407312},ISO,Europe/Berlin resolved 
to 2013-04-19T23:35:12 of type java.time.format.Parsed

如何解析我的日期时间字符串,以便将其解释为始终来自“欧洲/柏林”时区?

【问题讨论】:

标签: java java-8 java-time


【解决方案1】:

问题是ZoneIdZoneOffset 是有区别的。要创建OffsetDateTime,您需要一个区域偏移量。但是there is no one-to-one mapping between a ZoneId and a ZoneOffset 因为它实际上取决于当前的夏令时。对于像“Europe/Berlin”这样的ZoneId,夏季有一个偏移量,冬季有一个不同的偏移量。

在这种情况下,使用ZonedDateTime 而不是OffsetDateTime 会更容易。在解析过程中,ZonedDateTime 将正确设置为 "Europe/Berlin" 区域 id,并且还将根据要解析的日期的夏令时设置偏移量:

public static void main(String[] args) {
    String datum = "20130419233512";
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(ZoneId.of("Europe/Berlin"));
    ZonedDateTime datetime = ZonedDateTime.parse(datum, formatter);

    System.out.println(datetime.getZone()); // prints "Europe/Berlin"
    System.out.println(datetime.getOffset()); // prints "+02:00" (for this time of year)
}

请注意,如果您确实需要OffsetDateTime,可以使用ZonedDateTime.toOffsetDateTime()ZonedDateTime 转换为OffsetDateTime

【讨论】:

  • 我喜欢您一步完成,而不是像我展示的那样分两步完成。我会留下我的答案,因为两者都可以,但我会推荐你​​的绿色复选标记。 :)
  • 因为我需要 OffsetDateTime 我现在使用 OffsetDateTime datetime = ZonedDateTime.parse(datum, formatter).toOffsetDateTime(); .
  • @asmaier 是的,我也是这么评论的。您可以使用它转换为OffsetDateTime
【解决方案2】:

您的源数据中没有偏移量,因此OffsetDateTime 不是解析期间使用的正确类型。

改为使用LocalDateTime,因为这是与您拥有的数据最相似的类型。然后使用atZone为其分配时区,如果您仍然需要OffsetDateTime,可以从那里调用toOffsetDateTime

String datum = "20130419233512";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
LocalDateTime datetime = LocalDateTime.parse(datum, formatter);
ZonedDateTime zoned = datetime.atZone(ZoneId.of("Europe/Berlin"));
OffsetDateTime result = zoned.toOffsetDateTime();

【讨论】:

  • 谢谢。这对我行得通。我以某种方式假设 OffsetDateTime.parse() 方法会在内部为我执行这些步骤。
  • 这个工作完美,我不知何故认为和OP一样。这看起来很整洁!
猜你喜欢
  • 2019-12-04
  • 2019-04-16
  • 2018-01-01
  • 2021-05-13
  • 2020-07-29
  • 1970-01-01
  • 2022-12-13
  • 2017-09-29
  • 2016-06-26
相关资源
最近更新 更多