2016-05-17 6 views
6

Dlaczego następujące czynności nie działają, a ciąg daty i czasu nie może zostać przeanalizowany jako OffsetDateTime?Dlaczego `GMT + 8` nie parsuje ze wzorcem` O` mimo skopiowania z dokumentu?

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

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

Generuje błąd:

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

offset-from-UTC ciąg GMT+8 kopiowany jest wklejony z przykładu w dokumentacji klasy dla DateTimeFormatter. Zacytować:

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'.


Reszta napisu analizuje powodzeniem jako LocalDateTime. Tak więc problem wydaje się być częścią offset-from-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


Obejście

Częściowym rozwiązaniem jest dodanie spacją zarówno ciągu wejściowego i wzorca formatowania. To działa.

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 

Ale dodanie minut bez dwukropka jest udokumentowane jak pracować z jednym O ale to się nie powiedzie. To obejście problemu SPACE nie pomaga w takim przypadku. Zwróć uwagę na GMT+0800 w tym przykładzie w porównaniu z GMT+08 widzianą bezpośrednio powyżej, gdzie ten przykład kończy się niepowodzeniem, ale powyższy kod się powiódł.

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

fakt, że jest to 'StringIndexOutOfBoundsException' sprawia mi, że to jest bug –

+2

@SotiriosDelimanolis masz go.. Https: // bugs. openjdk.java.net/browse/JDK-8154050 – Andreas

+0

Wygląda na obejście problemu: dołączanie spacji zarówno do ciągu formatowania, jak i tekstu do analizy. –

Odpowiedz

2

Wydaje się być błędem w Javie. Zobacz 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

A w komentarzu:

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

Wydaje została ona ustalona w Java 9 build b116.

0

Mam ten sam problem.
Mój ciąg znaków jest podobny do "28.04.2010 09:39:33 UTC + 2".

Muszę dodać 0 do offsetu ("UTC + 02"). aby to przeanalizować. Jako wzór używam:

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

Jak przesunięcie może wynosić zero ("UTC" lub "strefie" bez numerów), używam DateTimeFormatterBuilder:

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

Gdzie "X" strefa-offset ...

Ale wtedy też trzeba:

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

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

naprawdę niewygodne ...:-(

Mam nadzieję java 9 zrobi właściwą pracę

Powiązane problemy