java.time.OffsetDateTime: невозможно получить OffsetDateTime из TemporalAccessor
Я пытаюсь разобрать "20140726080320+0400"
с помощью "yyyyMMddHHmmssZ"
отформатировать следующим образом:
System.out.println("********************" + OffsetDateTime
.parse("20140726080320+0400",
DateTimeFormatter.ofPattern("yyyyMMddHHmmssZ").withChronology(IsoChronology.INSTANCE).withResolverStyle(STRICT))
.toEpochSecond());
Я продолжаю сталкиваться с этим исключением:
java.time.format.DateTimeParseException: Text '20140726080320+0400' could not be parsed: Unable to obtain OffsetDateTime from TemporalAccessor: {OffsetSeconds=14400, DayOfMonth=26, YearOfEra=2014, MonthOfYear=7},ISO resolved to 08:03:20 of type java.time.format.Parsed
at java.time.format.Parsed.getLong(Parsed.java:203)
at java.time.Instant.from(Instant.java:373)
at java.time.OffsetDateTime.from(OffsetDateTime.java:365)
at java.time.format.Parsed.query(Parsed.java:226)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
at java.time.OffsetDateTime.parse(OffsetDateTime.java:402)
Что я делаю неправильно?
3 ответа
yyyy
в формате шаблон строки для года эры. Строго говоря, 2014 год может обозначать 2014 год до н.э. ("до Рождества Христова") или 2014 год н.э. ("год назад"). Видимо форматировщик со строгими объектами стиля решателя к этой неоднозначности.
Решение заключается в использовании uuuu
на год. Это подписанный год, где 0 означает 1 год до н.э., -1 означает 2 год до н.э. и т. Д. Поэтому нет никакой двусмысленности:
System.out.println("********************"
+ OffsetDateTime.parse("20140726080320+0400",
DateTimeFormatter.ofPattern("uuuuMMddHHmmssZ")
.withChronology(IsoChronology.INSTANCE)
.withResolverStyle(STRICT))
.toEpochSecond());
Это печатает
********************1406347400
Это связано с тем, как IsoChronology
разрешает дату для разных стилей распознавателя, как описано в javadoc:
Если присутствует только YEAR_OF_ERA, а режим интеллектуальный или снисходительный, то предполагается текущая эпоха (CE/AD). В строгом режиме эра не предполагается, и YEAR_OF_ERA остается нетронутым.
Возможно мой ответ устарел, но я только что сталкивался с похожей проблемой -)
если вы хотите использовать строгий режим и продолжать использовать «уууу» вместо «уууу», то вам необходимо добавить указание ERA. Я использовал значение по умолчанию, например:
OffsetDateTime.parse("20140726080320+0400",
new DateTimeFormatterBuilder()
.appendPattern("yyyyMMddHHmmssZ")
.parseDefaulting(ChronoField.ERA, 1)
.toFormatter()
.withResolverStyle(ResolverStyle.STRICT)
);
Этот код работает правильно. Я надеюсь, что это помогает кому-то.
Попробуй это:
LocalDateTime.parse("20140726080320+0400",
new DateTimeFormatterBuilder().appendPattern("yyyyMMddHHmmssZ").toFormatter())
.atOffset(ZoneOffset.UTC)
Возврат:
2014-07-26T08: 03: 20
Это неправильно, потому что игнорирует смещение (+0400) и затем устанавливает дату / время в UTC - что даст неверное значение для epochSecond