2016-05-16 54 views
5

Sto cercando di usare Java 8 nuovo Data motivo invece di Joda e ho il seguente problema:Java 8 LocalDateTime ZonedDateTime non può analizzare la data con il fuso orario

Sia

ZonedDateTime.parse("02/05/16 11:51.12.083 +04:30", DateTimeFormatter.ofPattern("dd/MM/yy HH:mm.ss.SSS Z")) 

e

LocalDateTime.parse("02/05/16 11:51.12.083 +04:30", DateTimeFormatter.ofPattern("dd/MM/yy HH:mm.ss.SSS Z")) 

tiro eccezione 'java.time.format.DateTimeParseException'. Mentre

org.joda.time.DateTime.parse("02/05/16 11:51.12.083 +04:30", DateTimeFormat.forPattern("dd/MM/yy HH:mm.ss.SSS Z")) 

funziona correttamente.

Causa della eccezione è:

java.time.format.DateTimeParseException: Testo '02/05/16 11: 51.12.083 +04: 30' non poteva essere analizzato con indice 22

sto facendo qualcosa di sbagliato?

+2

Hai provato OffsetDateTime? Non contiene informazioni sufficienti per conoscere un fuso orario effettivo; tutto ciò che trasporta è lo scostamento da UTC. –

+0

Sebbene dall'esempio in [docs] (https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html), sembra che i due punti siano accettati come delimitatore di offset di zona ma quando lo provi, genera un'eccezione. se togli solo i due punti dovrebbe funzionare. quindi la tua stringa datetime dovrebbe essere '02/05/16 11: 51.12.083 + 0430' –

+0

@Hank DI ha provato questo OffsetDateTime.parse (" 02/05/16 11: 51.12.083 +04: 30 ", DateTimeFormatter.ofPattern ("dd/MM/YY HH: mm.ss.SSS Z")) ma ottengo comunque la stessa eccezione. – ampofila

risposta

5

Se leggete the javadoc of DateTimeFormatter, troverete una sezione in dettaglio come utilizzare l'offset Z (sottolineatura mia):

Offset Z: questo formato l'offset in base al numero di lettere del modello. Una, due o tre lettere emette l'ora e il minuto, senza i due punti, come '+0130'. L'uscita sarà '+0000' quando l'offset è zero. Quattro lettere emettono la forma completa di offset localizzato, equivalente a quattro lettere di Offset-O. L'output sarà il testo di offset localizzato corrispondente se l'offset è zero. Cinque lettere uscite ora, minuti, con il secondo opzionale se non nullo, con colon. Emette 'Z' se l'offset è zero. Sei o più lettere generano IllegalArgumentException.

Quindi, utilizzando 5 Z s funzionerà come previsto:

ZonedDateTime.parse("02/05/16 11:51.12.083 +04:30", 
        DateTimeFormatter.ofPattern("dd/MM/yy HH:mm.ss.SSS ZZZZZ")); 

noti che è possibile ottenere risultati simili con:

  • z
  • zz
  • zzz
  • zzzz
  • xxx
  • XXX
  • xxxxx
  • XXXXX
0

È necessario utilizzare XXX per la differenza di fuso. Questo lavoro per ZonedDateTime e OffsetDateTime

ZonedDateTime.parse("02/05/16 11:51.12.083 +04:30", DateTimeFormatter.ofPattern("dd/MM/yy HH:mm.ss.SSS XXX")) 

Sarà analizzare con LocalDateTime pure, ma la differenza di fuso verrà troncato.

+0

Ho provato questo, sempre la stessa eccezione. (ZonedDateTime.parse ("02/05/16 11: 51.12.083 +04: 30", DateTimeFormatter.ofPattern ("gg/MM/AA HH: mm.ss.SSS X"))) – ampofila

1

ho trovato la risposta in questo post Unparsable Date with colon-separated timezone

Al fine di analizzare un timestamp che porta un fuso orario con un punto e virgola al posto di X o Z come il javadoc DateFormatter indica, è necessario utilizzare XXX. Tutti i seguenti lavori:

LocalDateTime.parse("02/05/16 11:51.12.083 +04:30", DateTimeFormatter.ofPattern("dd/MM/yy HH:mm.ss.SSS XXX")) 

OffsetDateTime.parse("02/05/16 11:51.12.083 +04:30", DateTimeFormatter.ofPattern("dd/MM/yy HH:mm.ss.SSS XXX")) 

ZonedDateTime.parse("02/05/16 11:51.12.083 +04:30", DateTimeFormatter.ofPattern("dd/MM/yy HH:mm.ss.SSS XXX")) 
0

Utilizzando DateTimeFormatterBuilder per ottenere il controllo esatto del parser e utilizzare appendOffsetId opere:

DateTimeFormatter formatter = new DateTimeFormatterBuilder() 
     .appendValue(ChronoField.DAY_OF_MONTH, 2) 
     .appendLiteral('/') 
     .appendValue(ChronoField.MONTH_OF_YEAR, 2) 
     .appendLiteral('/') 
     .appendValueReduced(ChronoField.YEAR, 2, 2, 2000) 
     .appendLiteral(' ') 
     .appendValue(ChronoField.HOUR_OF_DAY) 
     .appendLiteral(':') 
     .appendValue(ChronoField.MINUTE_OF_HOUR) 
     .appendLiteral('.') 
     .appendValue(ChronoField.SECOND_OF_MINUTE) 
     .appendLiteral('.') 
     .appendValue(ChronoField.MILLI_OF_SECOND) 
     .appendLiteral(' ') 
     .appendOffsetId() 
     .toFormatter(); 

OffsetDateTime.parse("02/05/16 11:51.12.083 +04:30", formatter);