анализ DateTime с помощью ThreetenBp вызывает исключение DateTimeParseException или ошибку неполной строки
Я пытаюсь проверить, прошла ли дата более одного дня или нет.
И я получил эти ошибки, пока он разбирает строку.
java.lang.IllegalArgumentException: Pattern ends with an incomplete string literal: uuuu-MM-dd'T'HH:mm:ss'Z
org.threeten.bp.format.DateTimeParseException: Text '2020-04-04T07:05:57+00:00' could not be parsed, unparsed text found at index 19
Мой пример данных здесь:
val lastDate = "2020-04-04T07:05:57+00:00"
val serverFormat = "uuuu-MM-dd'T'HH:mm:ss'Z"
val serverFormatter =
DateTimeFormatter
.ofPattern(serverFormat)
val serverDateTime =
LocalDateTime
.parse(
lastDate,
serverFormatter
)
.atZone(ZoneId.of("GMT"))
val clientDateTime =
serverDateTime
.withZoneSameInstant(ZoneId.systemDefault())
val timeDiff =
ChronoUnit.DAYS.between(
serverDateTime,
clientDateTime
Я пробовал с этим:
uuuu-MM-dd\'T\'HH:mm:ss\'Z
yyyy-MM-dd\'T\'HH:mm:ss\'Z
uuuu-MM-dd\'T\'HH:mm:ss
uuuu-MM-dd'T'HH:mm:ss'Z
yyyy-MM-dd'T'HH:mm:ss'Z
uuuu-MM-dd'T'hh:mm:ss'Z
yyyy-MM-dd'T'hh:mm:ss'Z
yyyy-MM-dd HH:mm:ss
yyyy-MM-dd HH:mm:ssZ
yyyy-MM-dd'T'HH:mm:ss
yyyy-MM-dd'T'HH:mm:ssZ
yyyy-MM-dd'T'HH:mm:ss
И ни один из них не работал... Как правильно?
1 ответ
Вам не нужен явный форматировщик. На Java (потому что это то, что я могу написать):
String lastDate = "2020-04-04T07:05:57+00:00";
OffsetDateTime serverDateTime = OffsetDateTime.parse(lastDate);
ZonedDateTime clientDateTime
= serverDateTime.atZoneSameInstant(ZoneId.systemDefault());
System.out.println("serverDateTime: " + serverDateTime);
System.out.println("clientDateTime: " + clientDateTime);
Вывод в моем часовом поясе:
serverDateTime: 2020-04-04T07:05:57Z clientDateTime: 2020-04-04T09:05:57+02:00[Europe/Copenhagen]
Формат строки с вашего сервера - ISO 8601. Классы java.time анализируют наиболее распространенные варианты ISO 8601 по умолчанию, то есть без указания какого-либо средства форматирования.
Поскольку строка с вашего сервера имеет смещение по всемирному координированному времени, +00:00 и не имеет часового пояса, например Asia/Seoul, OffsetDateTime
это лучшее и наиболее подходящее время для этого. С другой стороны, время клиента имеет часовой пояс, поэтомуZonedDateTime
здесь хорошо.
Поскольку время сервера и клиента обозначает одно и то же время, разница всегда будет равна нулю:
Duration difference = Duration.between(serverDateTime, clientDateTime);
System.out.println(difference);
PT0S
Считывается как период времени 0 секунд (это тоже формат ISO 8601).
Если вы хотите узнать разницу между текущим временем и временем сервера, используйте now()
:
Duration difference = Duration.between(serverDateTime, OffsetDateTime.now());
System.out.println(difference);
Что пошло не так в вашем коде?
Во-первых, смещение UTC в вашей строке +00:00
. Ни одна буква шаблона форматаZ
ни буквальный Z
будет соответствовать этому. Так что не пытайся. Во-вторых, никогда не давайтеZ
как литерал, заключенный в одинарные кавычки в строке шаблона формата. КогдаZ
отображается как смещение, что является обычным явлением, вам нужно проанализировать его как смещение, а не как литерал. В-третьих, буквальный текст в строке шаблона формата должен иметь одинарную кавычку перед и одинарную кавычку после нее. Вы делаете это правильно дляT
посередине. Если ты не имел в видуZ
чтобы быть буквальным, не ставьте перед ним ни одной кавычки. Если вы действительно имели в виду, что это буквально - как я уже сказал, просто не делайте этого.