simpledateformat дата разбора с литералом ' Z ' [дубликат]
этот вопрос уже есть ответ здесь:
Я пытаюсь разобрать дату, которая выглядит так:
2010-04-05T17:16:00Z
это допустимая дата для http://www.ietf.org/rfc/rfc3339.txt. литерал ' Z ' означает, что UTC есть предпочтительная точка отсчета для указанного времени."
Если я попытаюсь разобрать его с помощью SimpleDateFormat и этот шаблон:
yyyy-MM-dd'T'HH:mm:ss
он будет разбираться как Пн апр 05 17: 16: 00 EDT 2010
SimpleDateFormat не может разобрать строку с этими шаблонами:
yyyy-MM-dd'T'HH:mm:ssz
yyyy-MM-dd'T'HH:mm:ssZ
Я могу явно установить часовой пояс для использования на SimpleDateFormat, чтобы получить ожидаемый результат, но я не думаю, что это должно быть необходимо. Есть ли что-то, что я упускаю? Есть есть альтернативный парсер дат?
12 ответов:
в шаблоне включение компонента даты-времени " z " указывает на то, что формат часового пояса должен соответствовать общий часовой пояс "стандарт", примерами которого являются
Pacific Standard Time; PST; GMT-08:00
.A ' Z ' означает, что часовой пояс соответствует часовой пояс RFC 822 стандартные, например,
-0800
.Я думаю, что вам нужен DatatypeConverter ...
@Test public void testTimezoneIsGreenwichMeanTime() throws ParseException { final Calendar calendar = javax.xml.bind.DatatypeConverter.parseDateTime("2010-04-05T17:16:00Z"); TestCase.assertEquals("gotten timezone", "GMT+00:00", calendar.getTimeZone().getID()); }
Java не анализирует даты ISO правильно.
похоже на ответ Маккензи.
просто исправить
Z
перед разбором.код
String string = "2013-03-05T18:05:05.000Z"; String defaultTimezone = TimeZone.getDefault().getID(); Date date = (new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")).parse(string.replaceAll("Z$", "+0000")); System.out.println("string: " + string); System.out.println("defaultTimezone: " + defaultTimezone); System.out.println("date: " + (new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")).format(date));
результат
string: 2013-03-05T18:05:05.000Z defaultTimezone: America/New_York date: 2013-03-05T13:05:05.000-0500
дата, которую вы анализируете, находится в формате ISO8601.
в java 7 шаблон для чтения и применения суффикса часового пояса должен читать
yyyy-MM-dd'T'HH:mm:ssX
tl; dr
Instant.parse ( "2010-04-05T17:16:00Z" )
стандарт ИСО 8601
строка соответствует ISO 8601 стандарт (из которых упомянутый RFC 3339 профиль).
избегайте j.u. дата
java.утиль.Сроки и. Классы календаря в комплекте с Java, как известно, хлопотно. Избегать их.
вместо того, чтобы использовать Joda-Time библиотека или новая java.пакет времени в Java 8. Как использовать ISO 8601 как их значения по умолчанию для разбора и генерации строковых представлений значений даты-времени.
java.время
The java.время фреймворк встроен в Java 8 и позже вытесняет хлопотную старую java.утиль.Дата./Календарь занятий. Новые классы вдохновлены очень успешным Joda-Time фреймворк, задуманный как его преемник, похожий по концепции, но перестроенный. Определяется JSR 310. Продлен на ThreeTen-Extra. Смотрите учебник.
The
Instant
класс в java.время представляет собой момент на временной шкале в UTC часовой пояс.The
Z
в конце вашей входной строки означаетZulu
что означаетUTC
. Такая строка может быть непосредственно проанализирована с помощьюInstant
класс, без необходимости указывать форматер.String input = "2010-04-05T17:16:00Z"; Instant instant = Instant.parse ( input );
дамп в консоли.
System.out.println ( "instant: " + instant );
instant: 2010-04-05T17:16: 00Z
оттуда вы можете применить часовой пояс (
ZoneId
), чтобы отрегулировать этотInstant
наZonedDateTime
. Поиск переполнения стека для обсуждения и примеров.если вы должны использовать
java.util.Date
объект, который можно преобразовать, вызвав новые методы преобразования, добавленные к старым классам, таким как статический методjava.util.Date.from( Instant )
.java.util.Date date = java.util.Date.from( instant );
Joda Времени
пример в Joda-Time 2.5.
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" ): DateTime dateTime = new DateTime( "2010-04-05T17:16:00Z", timeZone );
преобразование в UTC.
DateTime dateTimeUtc = dateTime.withZone( DateTimeZone.UTC );
конвертировать в java.утиль.Дата при необходимости.
java.util.Date date = dateTime.toDate();
согласно последней строке на дата и время модели таблица Java 7 API
X часовой пояс ISO 8601 часовой пояс -08; -0800; -08:00
для часового пояса ISO 8601 вы должны использовать X (-08 или Z); XX(-0800 или Z); и XXX(-08:00 или Z), чтобы разобрать ваш "2010-04-05T17:16:00Z" либо "гггг-ММ-ДД не 'чч:мм:набором" или "гггг-ММ-ДД не 'чч:мм:ssXX" или "гггг-ММ-ДД не 'чч:мм:ssXXX" должны работать.
System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX").parse("2010-04-05T17:16:00Z")); System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXX").parse("2010-04-05T17:16:00Z")); System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").parse("2010-04-05T17:16:00Z"));
правильно распечатает 'Пн апр 05 13: 16: 00 EDT 2010'
'X' работает только в том случае, если частичные секунды отсутствуют: т. е. SimpleDateFormat pattern of
"yyyy-MM-dd'T'HH: mm: ssX"
будет правильно разбирать
"2008-01-31T00:00:00Z"
но
" yyyy-MM-dd'T'HH:mm:ss.SX"
разбирать не буду
"2008-01-31T00: 00: 00.000 Z"
грустно, но правда, дата-время с частичными секундами не кажется действительной датой ISO: http://en.wikipedia.org/wiki/ISO_8601
часовой пояс должен быть чем - то вроде "GMT+00:00" или 0000 для того, чтобы быть правильно проанализированы SimpleDateFormat-вы можете заменить Z с этой конструкцией.
проект restlet включает класс InternetDateFormat, который может анализировать даты RFC 3339.
хотя, вы можете просто заменить трейлинг ' Z ' на "UTC", прежде чем разбирать его.
Я даю еще один ответ, который я нашел
api-client-library
компания Googletry { DateTime dateTime = DateTime.parseRfc3339(date); dateTime = new DateTime(new Date(dateTime.getValue()), TimeZone.getDefault()); long timestamp = dateTime.getValue(); // get date in timestamp int timeZone = dateTime.getTimeZoneShift(); // get timezone offset } catch (NumberFormatException e) { e.printStackTrace(); }
установка guide,
https://developers.google.com/api-client-library/java/google-api-java-client/setup#downloadвот API reference,
https://developers.google.com/api-client-library/java/google-http-java-client/reference/1.20.0/com/google/api/client/util/DateTimeкод
DateTime
Class,
https://github.com/google/google-http-java-client/blob/master/google-http-client/src/main/java/com/google/api/client/util/DateTime.java
DateTime
единица измерения tests,
https://github.com/google/google-http-java-client/blob/master/google-http-client/src/test/java/com/google/api/client/util/DateTimeTest.java#L121
что касается JSR-310, то другим интересным проектом может быть threetenbp.
JSR-310 предоставляет новую библиотеку даты и времени для Java SE 8. Этот проект является обратным портом к Java SE 6 и 7.
в случае, если вы работаете на Android проект вы можете проверить библиотека ThreeTenABP.
compile "com.jakewharton.threetenabp:threetenabp:${version}"
JSR-310 был включен в Java 8 в качестве java.время.* пакет. Это полная замена для больных API даты и календаря как в Java, так и в Android. JSR-310 был возвращен на Java 6 его создателем, Стивеном Колборном, из которого эта библиотека адаптирована.