Не удалось получить ZonedDateTime от TemporalAccessor с помощью DateTimeFormatter и ZonedDateTime в Java 8
недавно я перешел на Java 8, Чтобы, надеюсь, легче справляться с локальными и зонированными временами.
тем не менее, я сталкиваюсь с, на мой взгляд, простой проблемой при разборе простой даты.
public static ZonedDateTime convertirAFecha(String fecha) throws Exception {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
ConstantesFechas.FORMATO_DIA).withZone(
obtenerZonaHorariaServidor());
ZonedDateTime resultado = ZonedDateTime.parse(fecha, formatter);
return resultado;
}
в моем случае:
- fecha is '15/06/2014'
- ConstantesFechas.FORMATO_DIA - это 'dd/MM / yyyy'
- obtenerZonaHorariaServidor возвращает ZoneId.systemDefault()
Итак, это простой пример. Тем не менее, разобрать выбрасывает это исключение:
java.time.format.DateTimeParseException: Text '15/06/2014' could not be parsed: Unable to obtain ZonedDateTime from TemporalAccessor: {},ISO resolved to 2014-06-15 of type java.time.format.Parsed
какие-либо советы? Я пробовал разные комбинации синтаксического анализа и использования TemporalAccesor, но до сих пор не повезло.
С наилучшими пожеланиями
5 ответов
Я не уверен, почему он не работает (возможно, потому, что ваш вход не имеет информации о времени/часовом поясе). Простой способ-проанализировать вашу дату как LocalDate
сначала (без информации о времени или часовом поясе) создайте ZonedDateTime
:
public static ZonedDateTime convertirAFecha(String fecha) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
LocalDate date = LocalDate.parse(fecha, formatter);
ZonedDateTime resultado = date.atStartOfDay(ZoneId.systemDefault());
return resultado;
}
это ошибка, см. JDK-bug-log. Согласно этой информации проблема была решена для Java 9 и Java 8u20. Попробуйте загрузить последнюю версию Java 8. Сегодня на 2014-05-12: есть ранний доступ релиз 8u20 доступен.
обновление:
лично я думаю, так как вы только и ожидаете "dd/MM/yyyy" в качестве шаблона вы должны использовать LocalDate
как ваш основной тип, как @assylias уже предложил. Относительно вашего контекст, он почти уверен, что отказ от дизайна использовать ZonedDateTime
. Что вы хотите делать с объектами такого типа? Я могу думать только о специализированных вычислениях часового пояса как о прецеденте. И вы даже не можете напрямую хранить эти ZonedDateTime
-объекты в базе данных, поэтому этот тип гораздо менее полезно, чем многие считают.
то, что я описал как вашу проблему с прецедентом, действительно является новым аспектом, введенным с Java-8 по сравнению со старым GregorianCalendar
- class (который является типом "все-в-одном"). Пользователи должны начать думать о выборе правильного временного типа для своих проблем и дел.
в строку
ZonedDateTime.parse('2014-04-23', DateTimeFormatter.ISO_OFFSET_DATE_TIME)
исключение:
Text '2014-04-23' could not be parsed at index 10
java.time.format.DateTimeParseException: Text '2014-04-23' could not be parsed at index 10
Это похоже на ошибку для меня.
я использовал этот метод:
String dateAsStr = '2014-04-23';
if (dateAsStr.length() == 10) {
dateAsStr += 'T00:00:00';
}
ZonedDateTime.parse(dateAsStr, DateTimeFormatter.ISO_OFFSET_DATE_TIME.withZone(ZoneId.systemDefault()));
просто пример преобразования, я считаю, что некоторые люди получат исключение ниже
(java.time.DateTimeException: Unable to obtain LocalDateTime from TemporalAccessor: 2014-10-24T18:22:09.800Z of type java.time.Instant)
если они попытаются
LocalDateTime localDateTime = LocalDateTime.from(new Date().toInstant());
чтобы решить проблему, пожалуйста, пройдите в зону -
LocalDateTime localDateTime = LocalDateTime.from(new Date()
.toInstant().atZone(ZoneId.of("UTC")));
Если из Google:
вместо:
ZonedDateTime.from(new Date().toInstant());
попробуйте это:
ZonedDateTime.ofInstant(new Date(), ZoneId.of("UTC"));