2014-05-11 13 views
18

ho recentemente trasferito a Java 8 a, si spera, si occupano con tempi locali e suddivisa in zone più facilmente.Impossibile ottenere ZonedDateTime da TemporalAccessor utilizzando DateTimeFormatter e ZonedDateTime in Java 8

Comunque, sto di fronte ad una, a mio parere, semplice problema quando analizza una data semplice.

public static ZonedDateTime convertirAFecha(String fecha) throws Exception { 
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
      ConstantesFechas.FORMATO_DIA).withZone(
      obtenerZonaHorariaServidor()); 

    ZonedDateTime resultado = ZonedDateTime.parse(fecha, formatter); 
    return resultado; 
} 

Nel mio caso:

  • fecha è '15/06/2014'
  • ConstantesFechas.FORMATO_DIA è 'dd/MM/yyyy'
  • obtenerZonaHorariaServidor torna ZoneId.systemDefault()

Quindi, questo è un semplice esempio. Tuttavia, il parse genera questa eccezione:

java.time.format.DateTimeParseException: Text '15/06/2014' could not be parsed: Unable to obtain ZonedDateTime from TemporalAccessor: {},ISO resolved to 2014-06-15 of type java.time.format.Parsed 

Qualche consiglio? Ho provato diverse combinazioni di analisi e utilizzo di TemporalAccesor, ma finora non ho avuto fortuna.

migliori saluti

risposta

19

io non sono sicuro perché non funziona (probabilmente perché il vostro input non ha informazioni sul fuso orario/ora). Un modo semplice è quello di analizzare la data come LocalDate prima (senza tempo e senza informazioni sul fuso orario) e poi creare un ZonedDateTime:

public static ZonedDateTime convertirAFecha(String fecha) { 
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); 
    LocalDate date = LocalDate.parse(fecha, formatter); 

    ZonedDateTime resultado = date.atStartOfDay(ZoneId.systemDefault()); 
    return resultado; 
} 
9

Questo è un bug, vedere JDK-bug-log. Secondo tali informazioni il problema è stato risolto per Java 9 e Java 8u20. Prova a scaricare la versione più recente di Java 8. Oggi su 2014/05/12: C'è un early access release 8u20 disponibili.

UPDATE:

Personalmente penso che, dal momento che hai solo e si aspettano "dd/MM/yyyy", come modello si dovrebbe usare LocalDate come tipo primario come @assylias ha già proposto. Per quanto riguarda il tuo contesto, è quasi certo fallimento di un disegno da utilizzare ZonedDateTime. Cosa vuoi fare con oggetti di questo tipo? Posso solo pensare ai calcoli del fuso orario specializzati come caso d'uso. E non si può nemmeno archiviare direttamente questi ZonedDateTime -Oggetti in un database, per cui questo tipo è molto meno utile di quanto molte persone credono.

Quello che ho descritto come problema del caso d'uso è in effetti un nuovo aspetto introdotto con Java-8 rispetto al vecchio GregorianCalendar -class (che è un tipo all-in-one). Gli utenti devono iniziare a pensare a scegliere il tipo temporale appropriato per i loro problemi e casi d'uso.

+1

Bella cattura - anche se credo che il PO avrebbe ancora bisogno di fornire un tempo di essere in grado di analizzare l'input in un ZonedDateTime. – assylias

+1

@assylias Sì, OP dovrebbe estendere il modello almeno anche per la parte temporale o scegliere il tuo suggerimento. Ciò potrebbe dipendere anche dalla configurazione di parsing di lenient, ecc. In realtà non sono in grado di testare questi dettagli con Java-8 sul mio posto corrente. –

+3

Link di segnalazione bug migliore è https://bugs.openjdk.java.net/browse/JDK-8033662 – JodaStephen

2

In parole semplici, la linea

ZonedDateTime.parse('2014-04-23', DateTimeFormatter.ISO_OFFSET_DATE_TIME) 

genera un'eccezione:

Text '2014-04-23' could not be parsed at index 10 
java.time.format.DateTimeParseException: Text '2014-04-23' could not be parsed at index 10 

Sembra un bug per me.

Ho usato questa soluzione:

String dateAsStr = '2014-04-23'; 
if (dateAsStr.length() == 10) { 
    dateAsStr += 'T00:00:00'; 
} 
ZonedDateTime.parse(dateAsStr, DateTimeFormatter.ISO_OFFSET_DATE_TIME.withZone(ZoneId.systemDefault())); 
+0

Questo è un dataTIME, quindi una stringa senza una parte di tempo non è un datetime valido ... – Koshinae

0

solo un esempio conversioni, credo che alcune persone avranno l'eccezione di seguito

(java.time.DateTimeException: Unable to obtain LocalDateTime from TemporalAccessor: 2014-10-24T18:22:09.800Z of type java.time.Instant) 

se cercano

LocalDateTime localDateTime = LocalDateTime.from(new Date().toInstant()); 

per risolvere il problema, si prega di passare in zona -

LocalDateTime localDateTime = LocalDateTime.from(new Date() 
     .toInstant().atZone(ZoneId.of("UTC"))); 
0

Se provenienti da Google:

Invece di fare:

ZonedDateTime.from(new Date().toInstant()); 

Prova questo:

ZonedDateTime.ofInstant(new Date(), ZoneId.of("UTC")); 
Problemi correlati