Синтаксический анализатор ThreeTenABP DateTime дает исключение для формата yyyy-MM-ddTHH:mm:ss
Мне нужно преобразовать дату и время
String
to millis, и я использую для этого ThreeTenABP, но
OffSetDateTime.parse
не может разобрать dateTime
String
что для ex.
"2020-08-14T20:05:00"
и дает следующее исключение.
Caused by: org.threeten.bp.format.DateTimeParseException:
Text '2020-09-22T20:35:00' could not be parsed:
Unable to obtain OffsetDateTime from TemporalAccessor:
DateTimeBuilder[, ISO, null, 2020-09-22, 20:35], type org.threeten.bp.format.DateTimeBuilder
Я уже просмотрел похожие вопросы, но не смог найти точного решения.
Ниже приведен код, который я использую в Котлине.
val formatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss",
Locale.ROOT)
val givenDateString = event?.eventDateTime
val timeInMillis = OffsetDateTime.parse(givenDateString, formatter)
.toInstant()
.toEpochMilli()
1 ответ
Проблема заключается в отсутствии смещения в
String
что вы пытаетесь разобрать на
OffsetDateTime
. An
OffsetDateTime
невозможно создать без
ZoneOffset
но нет
ZoneOffset
можно вывести из этого
String
(можно было просто догадаться, что это UTC, но угадывать в такой ситуации не годится).
Вы можете разобрать
String
к
LocalDateTime
(представление даты и времени без зоны или смещения), а затем добавьте / прикрепите желаемое смещение. Вам даже не нужен кастом
DateTimeFormatter
потому что твой
String
имеет формат ISO и может быть проанализирован с помощью встроенного средства форматирования по умолчанию:
fun main() {
// example String
val givenDateString = "2020-09-22T20:35:00"
// determine the zone id of the device (you can alternatively set a fix one here)
val localZoneId: ZoneId = ZoneId.systemDefault()
// parse the String to a LocalDateTime
val localDateTime = LocalDateTime.parse(givenDateString)
// then create a ZonedDateTime by adding the zone id and convert it to an OffsetDateTime
val odt: OffsetDateTime = localDateTime.atZone(zoneId).toOffsetDateTime()
// get the time in epoch milliseconds
val timeInMillis = odt.toInstant().toEpochMilli()
// and print it
println("$odt ==> $timeInMillis")
}
этот пример кода дает следующий результат (обратите внимание на конечный
Z
в представлении datetime это смещение
+00:00
часов, часовой пояс UTC, я написал этот код в Kotlin Playground, и кажется, что у него часовой пояс UTC;-)):
2020-09-22T20:35Z ==> 1600806900000
Обратите внимание, что я пробовал это с
java.time
а не с ThreeTen ABP, который сейчас устарел для многих (более низких) версий Android, поскольку есть Android API Desugaring. Однако это не должно иметь значения, потому что ваш примерный код выдал точно такое же исключение, когда я попробовал его сначала, а это значит, что ThreeTen не виноват в этом.