Я не знаю, Вавр. Мой ответ состоит из двух частей:
- Как разобрать вашу строку без Vavr.
- Как исправить решение Vavr, чтобы оно работало.
I не думаю, что вам нужно Vavr
String date = "2020-11-12T15:15:15.345";
DateTimeFormatter flexibleFormatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.optionalStart()
.appendLiteral('T')
.append(DateTimeFormatter.ISO_LOCAL_TIME)
.optionalStart()
.appendOffsetId()
.optionalEnd()
.optionalEnd()
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.OFFSET_SECONDS, 0)
.toFormatter();
OffsetDateTime value = OffsetDateTime.parse(date, flexibleFormatter);
System.out.println(value);
Вывод:
2020-11-12T15: 15: 15,345Z
Я пытался создайте средство форматирования, которое обрабатывает все варианты форматов, которые вы пытаетесь учесть в своей конструкции Vavr Try
.
Если вы предпочитаете исправить свое решение Vavr
Есть некоторые проблемы с средства форматирования, которые вы пытаетесь использовать в конструкции Vavr. Давайте исправим их по очереди.
.map(x->OffsetDateTime.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd")))
Разбор в формате yyyy-MM-dd
не даст вам достаточно информации для OffsetDateTime
. Вы будете получать дату, но не время суток и не смещение. Вместо этого я бы проанализировал LocalDate
и затем преобразовал бы:
.map(x->LocalDate.parse(date).atStartOfDay(ZoneOffset.UTC).toOffsetDateTime())
Я использую тот факт, что LocalDate
анализирует ваш формат по умолчанию без какого-либо явного средства форматирования. Метод one-arg atStartOfDay
дает нам ZonedDateTime
, поэтому после этого нам потребуется еще один шаг преобразования. Другое решение состояло бы в том, чтобы установить форматировщик со временем дня по умолчанию и смещением по умолчанию. Это будет похоже на то, что вы делаете в работающем устройстве форматирования, только с двумя вызовами parseDefaulting()
.
Следующий выпуск:
.map(x->OffsetDateTime.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS+HH:mm")))
Кажется, вы пытались разобрать строку как 2020-11-12T15:15:15.34+01:00
. +HH:mm
неверно для этого. HH
для часа дня и mm
для минуты часа. Но +01:00
в конце - это смещение от UT C, а не время дня, поэтому +HH:mm
не будет работать. Также +
является знаком, смещение также могло быть отрицательным, как -04:00
. Снова формат по умолчанию спасает нас, OffsetDateTime
анализирует строки, подобные упомянутой, без какого-либо явного форматера:
.map(x->OffsetDateTime.parse(date))
Формат по умолчанию - ISO 8601. Ссылка внизу.
.map(x->OffsetDateTime.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS+HH:mm")))
Это повторяет то, что вы пытались раньше, включая ту же ошибку. Это не вредит, но я предлагаю вам оставить это.
.map(x->OffsetDateTime.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS")))
Это должно соответствовать вашей «неизвестной» строке. Вы анализируете дату и время, но пропускаете смещение. Мое решение было бы разобрать в LocalDateTime
, а затем конвертировать. И снова формат ISO 8601 по умолчанию избавляет меня от создания средства форматирования.
.map(x->LocalDateTime.parse(date).atOffset(ZoneOffset.UTC))
Далее:
.map(x->OffsetDateTime.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ")))
Хотя я не знаю, я подозреваю, что вы пытались сопоставить строку с трейлинг Z
для UT C, например 2020-11-12T15:15:15.345Z
. Один аргумент OffsetDateTime.parse()
, использованный ранее, также принимает этот вариант, так что вы можете пропустить эту часть. Кстати, одна буква шаблона Z
предназначена для смещения без двоеточия, такого как +0000
, и не может анализировать Z
.
Далее:
.map(x->OffsetDateTime.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss")))
Снова мы пропускаем смещение, и опять это анализируется LocalDateTIme
ранее. В ISO 8601 доля секунды является необязательной, поэтому one-arg LocalDateTime.parse()
принимает строки как с, так и без. Оставьте эту часть.
Наконец:
.map(x->OffsetDateTime.parse(date, FORMATTER)) // DOSENT WORK
Я не могу сказать, почему это не работает, когда форматировщик работает изолированно. Я думаю, что это может быть что-то, определяемое Vavr c, которое я не понимаю. Тем не менее это заставляет меня задуматься. В любом случае о вашей строке должна была позаботиться одна из предыдущих записей, поэтому это может не иметь значения.
Ссылка