ThreeTenABP: DateTimeParseException
Попытка изменить форматы даты строки, но получить исключение 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 ответ
ТЛ; др
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[Америка /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 до некоторого часового пояса, примените ZoneId
чтобы получить ZonedDateTime
,
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[Америка / Лос-Анджелес]
С этими результатами мы видим, что 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 и более поздние версии - часть стандартного API Java со встроенной реализацией.
- Java 9 добавляет некоторые незначительные функции и исправления.
- Java SE 6 и Java SE 7
- Большая часть функциональности java.time перенесена на Java 6 и 7 в ThreeTen-Backport.
- Android
- Более поздние версии Android связывают реализации классов java.time.
- Для более ранних версий Android (<26) проект ThreeTenABP адаптирует ThreeTen-Backport (упомянутый выше). Смотрите Как использовать ThreeTenABP….
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Вы можете найти некоторые полезные классы здесь, такие как Interval
, YearWeek
, YearQuarter
и многое другое.