2016-02-09 10 views
6

Quando faccio questoImpossibile ottenere OffsetDateTime da TemporalAccessor

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

ottengo la seguente eccezione:

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 

Come posso analizzare la mia stringa datetime in modo che sia interpretata come sempre dalla fuso orario "Europa/Berlino"?

risposta

6

Il problema è che c'è una differenza tra ciò che una ZoneId è e ZoneOffset è. Per creare un OffsetDateTime, è necessario un offset di zona. Ma there is no one-to-one mapping between a ZoneId and a ZoneOffset perché in realtà dipende dall'ora legale attuale. Per lo stesso ZoneId come "Europa/Berlino", c'è un offset per l'estate e un diverso offset per l'inverno.

Per questo caso, sarebbe più semplice utilizzare uno ZonedDateTime anziché uno OffsetDateTime. Durante l'analisi, la ZonedDateTime sarà correttamente essere impostato per la "Europe/Berlin" zona di id e sarà anche essere impostato in base alla luce del giorno ora a tutti gli effetti di risparmio per la data di analizzare l'offset:

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) 
} 

Si noti che se si vuole veramente un OffsetDateTime , è possibile utilizzare ZonedDateTime.toOffsetDateTime() per convertire un ZonedDateTime in un OffsetDateTime.

+2

Mi piace che lo faccia in un solo passaggio, piuttosto che in due come ho mostrato. Lascerò la mia risposta poiché entrambi funzioneranno, ma consiglierei il vostro per il segno di spunta verde. :) –

+0

Poiché ho bisogno di OffsetDateTime ora utilizzo 'OffsetDateTime datetime = ZonedDateTime.parse (datum, formatter) .toOffsetDateTime();'. – asmaier

+1

@asmaier Sì, questo è quello che ho anche commentato. Puoi usarlo per convertire in un 'OffsetDateTime'. – Tunaki

1

Non c'è alcun offset nei dati di origine e quindi OffsetDateTime non è il tipo corretto da utilizzare durante l'analisi.

Invece, utilizzare uno LocalDateTime, poiché questo è il tipo che più assomiglia ai dati che si hanno. Quindi utilizza atZone per assegnargli un fuso orario e, se hai ancora bisogno di un OffsetDateTime, puoi chiamare lo toOffsetDateTime da lì.

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

Grazie. Per me va bene. In qualche modo ho pensato che il metodo OffsetDateTime.parse() avrebbe fatto questi passaggi internamente per me. – asmaier