2016-05-17 17 views
6

Perché non si riesce a eseguire quanto segue, con la stringa data/ora in grado di analizzare come OffsetDateTime?Perché `GMT + 8` non riesce ad analizzare con il pattern` O` nonostante sia stato copiato direttamente da doc?

String inputOdt = "2016-01-23T12:34:56 GMT+8"; 
DateTimeFormatter formatterOdt = DateTimeFormatter.ofPattern ("yyyy-MM-dd'T'HH:mm:ss O"); 
OffsetDateTime odt = OffsetDateTime.parse (inputOdt , formatterOdt); 

Utilizzando Java(TM) SE Runtime Environment (build 1.8.0_92-b14) su Mac OS X El Capitan 10.11.4.

genera l'errore:

Exception in thread "main" java.time.format.DateTimeParseException: Text '2016-01-23T12:34:56 GMT+8' could not be parsed: String index out of range: 25

Il offset-from-UTC stringa GMT+8 viene copiata-incollata dall'esempio nella documentazione classe per DateTimeFormatter. Per citare:

Offset O: This formats the localized offset based on the number of pattern letters. One letter outputs the short form of the localized offset, which is localized offset text, such as 'GMT', with hour without leading zero, optional 2-digit minute and second if non-zero, and colon, for example 'GMT+8'.


Il resto della stringa analizza con successo come LocalDateTime. Quindi il problema sembra essere la parte offset-da-UTC.

String inputLdt = "2016-01-23T12:34:56"; 
DateTimeFormatter formatterLdt = DateTimeFormatter.ofPattern ("yyyy-MM-dd'T'HH:mm:ss"); 
LocalDateTime ldt = LocalDateTime.parse (inputLdt , formatterLdt); 

System.out.println (""); 
System.out.println ("inputLdt: " + inputLdt); 
System.out.println ("ldt: " + ldt); 

inputLdt: 2016-01-23T12:34:56

ldt: 2016-01-23T12:34:56


Soluzione

Una soluzione parziale è quello di aggiungere uno spazio finale sia alla stringa di input e lo schema di formattazione. Quindi questo funziona.

String input = "Sat May 02 2015 00:00:00 GMT+08 "; // Trailing space. 
DateTimeFormatter formatter = DateTimeFormatter.ofPattern ("EEE MMM dd yyyy HH:mm:ss O "); // Trailing space. 
OffsetDateTime odt = OffsetDateTime.parse (input , formatter); // SUCCEEDS 

Ma l'aggiunta di minuti senza i due punti è documentato come lavorare con un unico O ma fallisce. Questa soluzione alternativa di uno SPACE finale non è di aiuto in questo caso. Notare GMT+0800 in questo esempio rispetto a GMT+08 visto direttamente sopra, dove questo esempio fallisce ma quello sopra ha esito positivo.

String input = "Sat May 02 2015 00:00:00 GMT+0800 "; // Minutes in the offset, and trailing space. 
DateTimeFormatter formatter = DateTimeFormatter.ofPattern ("EEE MMM dd yyyy HH:mm:ss O "); // Trailing space. 
OffsetDateTime odt = OffsetDateTime.parse (input , formatter); // FAILS 
+2

Il fatto che questo è un 'StringIndexOutOfBoundsException' mi fa pensare che questo è un bug –

+2

@SotiriosDelimanolis avete capito bene:.. Https: // bugs. openjdk.java.net/browse/JDK-8154050 – Andreas

+0

Sembra che una soluzione alternativa sia quella di aggiungere uno spazio sia alla stringa di formato sia al testo. –

risposta

2

Sembra un bug in Java. Vedi https://bugs.openjdk.java.net/browse/JDK-8154050:

java.time.format.DateTimeFormatter can't parse localized zone-offset

The DateTimeFormatter fails to parse its own output for format strings containing "O". The following code throws a StringIndexOutOfBoundsException on the final line.

import java.time.ZoneOffset 
import java.time.ZonedDateTime 
import java.time.format.DateTimeFormatter 
DateTimeFormatter formatter = DateTimeFormatter 
     .ofPattern("yyyy-MM-dd'T'HH:mm:ss.S O") 
     .withLocale(Locale.ENGLISH) 
String date = formatter.format(ZonedDateTime.now(ZoneOffset.UTC)); 
formatter.parse(date) 

ERROR MESSAGES/STACK TRACES THAT OCCUR : java.time.format.DateTimeParseException: Text '2016-04-08T10:49:52.7 GMT' could not be parsed: String index out of range: 25

E in un commento:

Attached test case executed on:
JDK 8 - Fail
JDK 8u77 - Fail
JDK 9EA - Fail

sembra sia stato risolto in Java 9 accumulo B116.

0

Ho lo stesso problema.
La mia stringa è qualcosa come "28.04.2010 09:39:33 UTC + 2".

Devo aggiungere un 0 allo scostamento ("UTC + 02"). per ottenerlo analizzato. Come modello che sto usando:

public final static String INPUT_PATTERN_DD_MM_YYYY_HH_mm_ss_zzz = "dd.MM.yyyy HH:mm:ss zzz"; 

come offset potrebbe essere pari a zero ("UTC" o "GMT" senza numeri), sto usando la DateTimeFormatterBuilder:

DateTimeFormatter formatter = new DateTimeFormatterBuilder().parseCaseInsensitive().append(df).optionalStart() 
      .appendPattern("X").optionalEnd().toFormatter(); 

Dove "X" la zona-offset ...

Ma poi ho anche bisogno:

 ZoneId id = ZoneOffset.ofHours(Integer.valueOf(offset)); 

     zonedDateTime = zonedDateTime.withZoneSameInstant(id); 
     zonedDateTime = zonedDateTime.minusHours(Integer.valueOf(offset)); 

davvero imbarazzante ...:-(

Spero java 9 farà il lavoro giusto

Problemi correlati