2015-06-08 28 views
9

Próbuję przeanalizować: 2014-05-02-10.45.05.993280-5:00, gdzie -5:00 jest przesunięciem od UTC. Używanie java.time DateTimeFormatter w języku Java 8.java.time DateTimeFormatter dla przesunięcia strefy czasowej

Dla pierwszego bitu mam: yyyy-MM-dd-HH.mm.ss.SSSSSS, ale nie mogę określić, jaki powinien być wzór do analizy offsetu.

Gdybym miał offset z 4 cyframi (-05: 00), mógłbym użyć: yyyy-MM-dd-HH.mm.ss.SSSSSSxxx, ale to nie działa dla 3 cyfr.

Wszelkie pomysły?

+1

Z której wersji Java korzystasz? –

+0

@JonSkeet - przepraszam, zaktualizowany oryginalny wpis. – Cheetah

Odpowiedz

9

Należy użyć dużej litery X zamiast x, stąd XXX. Różnica polega na tym, że duże X może rozpoznać literę wejściową "Z" jako przesunięcie UTC +00: 00, podczas gdy mała litera X nie może.

Sugerowane wzór:

yyyy-MM-dd-HH.mm.ss.SSSSSSXXX 

Należy również pamiętać o następujących JDK-bug:

java.time.format.DateTimeFormatter nie można analizować offset z pojedynczym cyfrowym godzinę

AKTUALIZACJA:

Przetestowałem opisane obejście w dzienniku błędów.

String input = "2014-05-02-10.45.05.993280-5:00"; 
DateTimeFormatter f = new DateTimeFormatterBuilder().appendPattern("yyyy-MM-dd-HH.mm.ss.SSSSSS").parseLenient().appendOffset("+HH:MM", "Z").toFormatter(); 
System.out.println(f.parse(input, ZonedDateTime::from)); 

Ale to zgłasza wyjątek:

Wyjątek w wątku "głównym" java.time.format.DateTimeParseException: Tekst „2014-05-02-10.45.05.993280-5: 00 'nie mógł być przeanalizowany w indeksie 26 w java.time.format.DateTimeFormatter.parseResolved0 (DateTimeFormatter.java:1947) w java.time.format.DateTimeFormatter.parse (DateTimeFormatter.java:1849) at HelloWorld.main (Witaj świecie.java: 16)

Tak łagodne parsowanie też nie pomaga. więc istnieje teraz tylko trzy opcje w lewo dla Ciebie:

  • Zastosowanie obejście sugerowane przez bug reporter: [...] Rozwiązaniem jest do analizowania datę/czas osobno, należy korzystać z zakodowaną parser dla offsetu i połączyć LocalDateTime z przesunięciem ręcznym. Nie jest to łatwa praca.

  • Wypróbuj własny specjalistyczny przerób struny. Jeśli masz stały format, możesz spróbować wstawić cyfrę zero w pozycji 26 (jeśli całkowita długość wejściowa jest o jedną cyfrę zbyt mała).

  • Albo używasz zewnętrznej biblioteki, która może to zrobić. Moja biblioteka Time4J (v4.0) może to zrobić, jeśli chcesz dodać dodatkową zależność. Zobacz ten kod:

String input = "2014-05-02-10.45.05.993280-5:00"; ZonalDateTime zdt = ZonalDateTime.parse( input, Moment.localFormatter("yyyy-MM-dd-HH.mm.ss.SSSSSSXXX", PatternType.CLDR)); System.out.println(zdt); // 2014-05-02T10:45:05,993280UTC-05:00 ZonedDateTime result = zdt.toTemporalAccessor();

Aktualizacja: Zgodnie z JDK-bug-statusu, błąd został naprawiony Java-9, ale backportu Java-8 nie wydaje się być dostępne jednak.

+0

Wzór nie działa ... ale link do błędu wygląda dokładnie na mój problem. Wypróbowałem sugestię producenta, ale to też nie działa. – Cheetah

+0

@Cheetah Masz rację. Przepraszamy, że cierpisz na błąd. Zobacz także moją aktualizację, jeśli możesz użyć dowolnego alternatywnego obejścia. –

2

offset dla SimpleDateFormat znak jest Z check Java7 lub Java8SimpleDateFormat API.

Następnie Twój Format parser dla String

2014-05-02-10.45.05.993280-5:00 

musi być:

yyyy-MM-dd-HH.mm.ss.SSSSSSZ 

UPDATE: dla DateTimeFormatter offsetowe Wzory do formatowania i parsowania są:

O  localized zone-offset  offset-O   GMT+8; GMT+08:00; UTC-08:00; 
X  zone-offset 'Z' for zero offset-X   Z; -08; -0830; -08:30; -083015; -08:30:15; 
x  zone-offset     offset-x   +0000; -08; -0830; -08:30; -083015; -08:30:15; 
Z  zone-offset     offset-Z   +0000; -0800; -08:00; 

Twój żądany wzór w DateTimeFormatter to X.

+0

Używam 'DateTimeFormatter' i dodawanie' Z' nie pojawia się ot pracy – Cheetah

+1

Połączyłeś się z Java 7 dwukrotnie. [Java 8 API jest tutaj.] (Http://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html) – dcsohl