ThreeTenABP: DateTimeParseException - PullRequest
       53

ThreeTenABP: DateTimeParseException

0 голосов
/ 18 декабря 2018

Попытка изменить форматы даты в строке, но получило исключение DateTimeException:

String oldDate = "2018-12-18T17:04:56+00:00";
String outputFormat = "DD-MM";
try {
    Instant instant = Instant.parse(oldDate);
    LocalDateTime localDateTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime();
    return localDateTime.format(DateTimeFormatter.ofPattern(outputFormat);
} catch (DateTimeException | IllegalArgumentException e) {
    Log.e("Error", e.getLocalizedMessage());
    return "";
}

Ошибка, которую я получаю: Текст '2018-12-18T17: 04: 56 + 00: 00' можетне обрабатывается по индексу 19

Я использую com.jakewharton.threetenabp: threetenabp: 1.1.1, поскольку не могу использовать классы Java 8

1 Ответ

0 голосов
/ 19 декабря 2018

tl; др

OffsetDateTime.parse(                // Represent a moment, a date with time-of-day in the context of an offset-from-UTC (some number of hours-minutes-seconds).
    "2018-12-18T17:04:56+00:00"      // Input string in standard ISO 8601 format, with an indicator of an offset-from-UTC of zero hours and zero minutes, meaning UTC itself.
)                                    // Returns an `OffsetDateTime` object.
.atZoneSameInstant(                  // Adjust our moment from UTC to the wall-clock time used by the people of a particular region (a time zone).
    ZoneId.systemDefault()           // Using the JVM’s current default time zone. NOTE: this default can change at any moment during runtime. If important, confirm with the user.
)                                    // Returns a `ZonedDateTime` object.
.toString()                          // Generate text in standard ISO 8601 format wisely extended by appending the name of the zone in square brackets. Returns a `String` object.

2018-12-18T09: 04: 56-08: 00 [America / Los_Angeles]

Подробнее

Вот пример кода Java с использованием ThreeTen-Backport проекта, который расширен на ThreeTenABP для Android до 26.

import org.threeten.bp.*;

Неправильный форматер

Команда Instant.parse использует форматер DateTimeFormatter.ISO_INSTANT.Этот форматер ожидает, что Z в конце указывает UTC.

Класс Instant является базовым классом строительных блоков фреймворка java.time .Для большей гибкости используйте OffsetDateTime.Форматировщик по умолчанию DateTimeFormatter.ISO_OFFSET_DATE_TIME может обрабатывать ваш ввод.

String input = "2018-12-18T17:04:56+00:00";
OffsetDateTime odt = OffsetDateTime.parse( input );

odt.toString (): 2018-12-18T17: 04: 56Z

Неправильный класс

Не используйте LocalDateTime для отслеживания момента.В этом классе намеренно отсутствует понятие часовой пояс или смещение от UTC .Это просто дата и время суток.Таким образом, не может представлять момент, никогда не является точкой на временной шкале.Вместо этого этот класс представляет потенциальных моментов в диапазоне 26-27 часов, диапазоне часовых поясов по всему земному шару.

Для отслеживания момента используйте только:

  • InstantМомент в UTC, всегда UTC.
  • OffsetDateTimeДата, время суток, со смещением от UTC.Смещение - это просто количество часов-минут-секунд, не более.
  • ZonedDateTimeМомент, который виден сквозь настенные часы, используемые людьми определенного региона, часового пояса.Зона - это история прошлых, настоящих и будущих изменений смещения, используемого в конкретном регионе.

Чтобы настроить OffsetDateTime от UTC до некоторого часового пояса, примените ZoneIdZonedDateTime.

ZoneId z = ZoneId.systemDefault() ;  // If important, confirm the zone with user rather than depending on the JVM’s current default zone.
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;

zdt.toString (): 2018-12-18T09: 04: 56-08: 00 [America / Los_Angeles]

С этими результатами мы видим, что 17:00 в UTC - это одновременно 9:00 на большей части западного побережья Северной Америки.Разница в -08:00 означает, что на эту дату западное побережье было на восемь часов позади UTC.


О 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 SE 10, Java SE 11 и более поздних версий - часть стандартного Java API с связанной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и JavaSE 7
    • Большинство функций java.time перенесено в Java 6 & 7 в ThreeTen-Backport .
  • Android
    • Более поздние версии реализации связки Android java.time классы.
    • Для более ранних версий Android (<26) проект <a href="https://github.com/JakeWharton/ThreeTenABP" rel="nofollow noreferrer"> ThreeTenABP адаптируется ThreeTen-Backport (упомянуто выше).См. Как использовать ThreeTenABP… .

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

...