Почему можно передать объект LocalDateTime в метод ZonedDateTime.from(), если это не представляется возможным разобрать простой DateTime?
Оба LocalDateTime и ZonedDateTime реализует интерфейс под названием Temporal, который простирается TemporalAccessor.
LocalDateTime является дата-время без временной зоны в календарной системе ISO-8601, например, 2007-12-03T10: 15: 30
ZonedDateTime является дата-время с временной зоной в ISO -8601, например, 2007-12-03T10: 15: 30 + 01: 00 Европа/Париж.
Теперь, если вы видите, что метод from(TemporalAccessor temporal)
, который ожидает TemporalAccessor. Как ZonedDateTime, так и LocalDateTime реализуют метод суперинтерфейса TemporalAccessor (Temporal extends TemporalAccessor), это нормально (полиморфное поведение), чтобы мы могли передавать как локальное, так и Zoned дату.
Код:
public static ZonedDateTime from(TemporalAccessor temporal) {
if (temporal instanceof ZonedDateTime) {
return (ZonedDateTime) temporal;
}
try {
ZoneId zone = ZoneId.from(temporal);
if (temporal.isSupported(INSTANT_SECONDS)) {
long epochSecond = temporal.getLong(INSTANT_SECONDS);
int nanoOfSecond = temporal.get(NANO_OF_SECOND);
return create(epochSecond, nanoOfSecond, zone);
} else {
LocalDate date = LocalDate.from(temporal);
LocalTime time = LocalTime.from(temporal);
return of(date, time, zone);
}
} catch (DateTimeException ex) {
throw new DateTimeException("Unable to obtain ZonedDateTime from TemporalAccessor: " +
temporal + " of type " + temporal.getClass().getName(), ex);
}
}
Теперь мы подошли к вашей проблеме.
Вы передаете LocalDateTime.parse("2016-08-31T23:00:59")
методу from(TemporalAccessor temporal)
.Таким образом, временный не является экземпляром ZonedDateTime, он приходит ZoneId zone = ZoneId.from(temporal)
;
Так вы получаете ошибку, так как LocalDateTime не содержит часовой пояс .
Как решить проблему?
Используйте Id зоны с ZonedDateTime
LocalDateTime ldt = LocalDateTime.parse("2016-08-31T23:00:59");
ZoneId zoneId = ZoneId.of("Europe/Paris");
ZonedDateTime zdt = ldt.atZone(zoneId);
GregorianCalendar gc = GregorianCalendar.from(zdt);
С теста JUnit
@Test
public void test() throws Exception {
ZoneId zoneId = ZoneId.of("Europe/Paris");
GregorianCalendar.from(LocalDateTime.parse("2016-08-31T23:00:59").atZone(zoneId));
}
вы спрашиваете, как преобразовать в 'GregorianCalendar', или вы спрашиваете, почему он позволяет передать внедрение интерфейса «TemporalAccessor» и только жалуется на это во время выполнения? – RealSkeptic
GeorgianCalendar требует часовой пояс, поэтому на самом деле вы можете сделать 'GregorianCalendar.from (ZonedDateTime.parse (« 2016-08-31T23: 00: 59 + 00: 00 »));' предоставление часового пояса. 'ZonedDateTime.from' может терпеть неудачу для разных типов ввода и указанного в javadoc. – vsminkov
Диаграмма, показывающая преобразования из старых классов времени-времени в java.time в [мой ответ] (http://stackoverflow.com/a/36639155) в [Конвертировать java.util.Date в тип «java.time» ?] (http://stackoverflow.com/q/36639154) может оказаться полезным. Также найдите пример кода преобразования в обоих направлениях. –