DateTimeParseException: текст '2019-06-07 12:18:16' не может быть проанализирован - PullRequest
0 голосов
/ 07 июня 2019

У меня есть следующий код для преобразования Instant в String, а затем преобразование его обратно в I

String timestampString = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss"));
LOGGER.info("timestampString: " + timestampString);

Instant instant =
    LocalDateTime.parse(timestampString,
        DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss")).toInstant(ZoneOffset.UTC);

, которое печатает timestampString как: 2019-06-07 12:45:57

и не удалось проанализировать строку:

java.time.format.DateTimeParseException: Text '2019-06-07 12:45:57' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {MinuteOfHour=45, HourOfAmPm=0, NanoOfSecond=0, SecondOfMinute=57, MilliOfSecond=0, MicroOfSecond=0},ISO resolved to 2019-06-07 of type java.time.format.Parsed

почему он не может разобрать его, даже если это тот же формат, в который я конвертирую метку времени?

1 Ответ

2 голосов
/ 08 июня 2019

Используйте ЧЧ для часа дня вместо чч

Проблема, о которой вы спрашиваете, заключается в том, что вы используете строчную букву hh в строке шаблона формата (оба раза). Вам нужен верхний регистр HH для часового дня с 00 по 23. hh для часа в течение AM или PM с 01 до 12. Итак, что пошло не так, так это то, что java.time не знал, ссылался ли 12 в вашей строке до 12:00 или 12:00 и отказались угадать для вас.

Если вы внимательно прочитаете сообщение об исключении, вы также заметите, что в нем говорится, что HourOfAmPm=0 был проанализирован. Это не говорит HourOfDay.

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    String timestampString = LocalDateTime.now().format(formatter);
    System.out.println("timestampString: " + timestampString);

    Instant instant = LocalDateTime.parse(timestampString, formatter)
            .toInstant(ZoneOffset.UTC);

    System.out.println("instant: " + instant);

Когда я только что запустил этот фрагмент, я получил такой вывод:

timestampString: 2019-06-08 19:22:51
instant: 2019-06-08T19:22:51Z

Это неправильно ! Я запускал фрагмент около 17:22 UTC, а не 19:22. Поскольку Дания все еще использует летнее время (черт), местное время здесь было 19:22, которое использовалось для результата и переводилось в то же время в UTC, а не в тот же момент времени. Вы должны всегда передавать желаемый часовой пояс методу now, чтобы избежать таких ошибок. Так как вы хотели UTC:

    String timestampString = LocalDateTime.now(ZoneOffset.UTC).format(formatter);
timestampString: 2019-06-08 17:27:57
instant: 2019-06-08T17:27:57Z

Еще лучше, не используйте LocalDateTime для хранения чего-то, что вы хотите использовать в данный момент. Вместо этого используйте Instant, OffsetDateTime или ZonedDateTime.

Более подробная информация об использовании hh, HH или kk для форматирования и анализа значений часов в этом вопросе и его ответах: Разница между java ЧЧ: мм и ЧЧ: мм в SimpleDateFormat . Вопрос в том, что касается печально известного SimpleDateFormat, но ответы действительны и для DateTimeFormatter.

...