Используйте ЧЧ для часа дня вместо чч
Проблема, о которой вы спрашиваете, заключается в том, что вы используете строчную букву 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
.