Часовой пояс Java при разборе DateFormat - PullRequest
9 голосов
/ 28 декабря 2010

У меня был код, который анализирует дату следующим образом:

String ALT_DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
SimpleDateFormat sdf = new SimpleDateFormat(
                    ALT_DATE_TIME_FORMAT);
Date date = sdf.parse(requiredTimeStamp);

И все работало нормально, вдруг перестало работать. Оказывается, администратор внес некоторые изменения в конфигурацию на сервере, и в настоящее время возвращается дата «2010-12-27T10: 50: 44.000-08: 00», которая не может быть проанализирована с помощью вышеуказанного шаблона. У меня два вопроса:

Во-первых, какой шаблон будет анализировать дату, возвращаемую JVM в указанном выше формате (в частности, просто '-08: 00' в качестве часового пояса)? И второе, где именно можно изменить такие настройки на сервере Linux RHEL 5, чтобы мы знали о таких изменениях в будущем?

Ответы [ 7 ]

11 голосов
/ 06 сентября 2016

tl; dr

OffsetDateTime.parse( "2010-12-27T10:50:44.000-08:00" )

ISO 8601

Формат входной строки определен в стандарте ISO 8601 , семействе форматов даты и времени.

Избегайте старых классов даты и времени

В Вопросе и других ответах используются старые устаревшие классы даты и времени, включенные в самые ранние версии Java.Избежать их.Теперь вытеснены классами java.time.

Использование java.time

Ваша строка ввода заканчивается offset-from-UTC .Таким образом, мы анализируем как объект OffsetDateTime.

Классы java.time по умолчанию используют форматы ISO 8601 при разборе / генерации строк.Поэтому нет необходимости указывать шаблон форматирования.

OffsetDateTime odt = OffsetDateTime.parse( "2010-12-27T10:50:44.000-08:00" );

Если вы хотите просмотреть это значение даты и времени в качестве момента на временной шкале в UTC, извлеките Instant.

Instant instant = odt.toInstant();

Часовой пояс - это смещение плюс набор правил для обработки аномалий, таких как летнее время (DST).Если у вас есть часовой пояс, примените ZoneId, чтобы получить ZonedDateTime объект.Тот же момент на временной шкале, но при просмотре через другое время настенных часов .

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = odt.atZoneSameInstant( z );  // Same moment on the timeline, but viewed through a different wall-clock time.

image


О java.time

Фреймворк java.time встроен в Java 8 и более поздние версии.Эти классы заменяют проблемные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar, & SimpleDateFormat.

Проект Joda-Time , теперь в режиме обслуживания , рекомендует перейти на классы java.time .

Чтобы узнать больше, см. Oracle Tutorial .И поиск переполнения стека для многих примеров и объяснений.Спецификация: JSR 310 .

. Вы можете обмениваться java.time объектами напрямую с вашей базой данных.Используйте драйвер JDBC , совместимый с JDBC 4.2 или более поздней версии.Нет необходимости в строках, нет необходимости в java.sql.* классах.

Где получить классы java.time?

  • Java SE 8 , Java SE 9 , а позже
    • Встроенный-в.
    • Часть стандартного Java API с встроенной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функций java.time перенесена на Java 6 & 7 в ThreeTen-Backport .
  • Android
    • Более поздние версии реализации связки Android классов java.time.
    • Для более ранних версий Android проект ThreeTenABP адаптируется ThreeTen-Бэкпорт (упоминается выше).См. Как использовать ThreeTenABP… .

ThreeTen-Extra Проект расширяет java.time дополнительными классами.Этот проект является полигоном для возможных будущих дополнений к java.time.Здесь вы можете найти некоторые полезные классы, такие как Interval, YearWeek, YearQuarter и more .

4 голосов
/ 28 декабря 2010

Другое приложение использует формат даты и времени ISO 8601.Я предполагаю, что другое приложение отправляет вам ответ XML, который соответствует типу dateTime схемы XML, то есть ISO 8601. Теперь известно, что DateFormat не может проанализировать этот формат.Вы должны использовать другие библиотеки, такие как joda-time (joda-time - победитель) или FastDateFormat, как указано в других ответах.Посмотрите на это сообщение Преобразование строки, соответствующей ISO 8601, в java.util.Date

1 голос
/ 10 декабря 2013

Использование JodaTime

В качестве более конкретного примера к предложению @ Pangea использовать JodaTime, вы можете использовать следующее:

String timestamp = "2012-09-17T04:11:46Z";

DateTime date = ISODateTimeFormat.dateTimeParser().parseDateTime(timestamp);

Это правильно распознает часовой пояс UTC. Я не пробовал это с миллисекундами в строке времени, но я уверен, что это будет работать так же хорошо.

Надежда, которая помогает другим.

JP

1 голос
/ 28 декабря 2010

Если вы хотите проанализировать его с помощью прямого JDK, я считаю, что он должен быть проанализирован с использованием утилит JAXB, см. DatatypeFactory.newXMLGregorianCalendar или DatatypeConverter.parseDateTime .

0 голосов
/ 28 декабря 2010

SimpleDateFormat принимает только -0800 или GMT-08:00 в качестве часового пояса.

Кажется, формат ISO 8601 не может быть проанализирован с SimpleDateFormat.Может быть, вам стоит взглянуть на Apache Commons Lang FastDateFormat .Он совместим с SimpleDateFormat, но принимает шаблон ZZ для часового пояса, который должен анализировать необходимый формат часового пояса. DateFormatUtils содержит несколько примеров констант, которые выглядят так, как вам нужно, без миллисекунд (например ISO_DATETIME_TIME_ZONE_FORMAT ).

0 голосов
/ 28 декабря 2010

Попробуйте изменить его на строчные буквы z.

z обрабатывает большую часть общего общего синтаксиса часового пояса, в то время как Z использует более строгий часовой пояс RFC 822 с 4 цифрами.

Хотя документально подтверждено, чтооба должны проанализировать «Общие настройки часового пояса», это может иметь значение в вашем случае.

0 голосов
/ 28 декабря 2010

Вопрос должен быть откуда requiredTimeStamp и в каком формате. Это вводится пользователем или читается из другой программы? Какой компонент создает дату в строковом представлении?

Формат "2010-12-27T10: 50: 44.000-08: 00" выглядит как стандартизированный формат ISO-8601 Должен быть разбираться с рисунком yyyy-MM-dd'T'HH:mm:ss.SSSZ

Не уверен, какие настройки влияют на это, но есть Oracle FAQ по Java TimeZones . Это может быть системное свойство user.timezone или символическая ссылка /etc/localtime в RHEL.

...