无法从TemporalAccessor获取OffsetDateTime

时间:2016-02-09 17:21:09

标签: java java-8 java-time

当我这样做时

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

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

2 个答案:

答案 0 :(得分:13)

问题在于ZoneIdZoneOffset之间存在差异。要创建OffsetDateTime,您需要一个区域偏移量。但是there is no one-to-one mapping between a ZoneId and a ZoneOffset因为它实际上取决于当前的夏令时。对于像“欧洲/柏林”这样的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

答案 1 :(得分:4)

源数据中没有偏移量,因此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();