2016-02-09 46 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