2016-02-09 43 views
6

获得OffsetDateTime当我这样做无法从TemporalAccessor

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 

如何可以解析我的时间字符串,以便它被解释为总是从正在时区“欧洲/柏林”?

回答

6

的问题是,有什么之间一个ZoneId是和ZoneOffset是有区别的。要创建一个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

+2

我喜欢你这样做,而不是像我所展示的那样。我会留下我的答案,因为两者都可以工作,但我建议你们选择绿色的选中标记。 :) –

+0

由于我需要OffsetDateTime我现在使用'OffsetDateTime datetime = ZonedDateTime.parse(datum,formatter).toOffsetDateTime();'。 – asmaier

+1

@asmaier是的,这就是我所评论的。你可以使用它来转换为'OffsetDateTime'。 – Tunaki

1

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

谢谢。这对我行得通。我以某种方式假定OffsetDateTime.parse()方法会为我内部执行这些步骤。 – asmaier