Используйте HH для часа дня вместо hh
Проблема, о которой вы спрашиваете, заключается в том, что вы используете строчные буквы hh
в строке шаблона формата (оба раза). Вам нужен верхний регистр HH
для часового дня с 00 до 23. hh
для часа в пределах AM или PM с 01 до 12. Итак, что пошло не так, так это то, что java.time не знал, относится ли 12
в вашей строке к 12 AM или 12 PM и отказался сделать предположение для вас.
Если вы внимательно прочитаете сообщение об исключении, вы также заметите, что в нем говорится, что 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 HH:mm и hh:mm в SimpleDateFormat. Вопрос касается общеизвестно неприятного SimpleDateFormat
, но ответы действительны и для DateTimeFormatter
.
person
Ole V.V.
schedule
08.06.2019
HH
, а неhh
.hh
— это 12-часовой час дня; вы хотите 24 часа в сутки. - person Jon Skeet   schedule 08.06.2019LocalDateTime.now()
использует системный часовой пояс, тогда как вы утверждаете, что он в формате UTC. Если бы вы могли предоставить больше контекста для того, чего вы пытаетесь достичь, мы могли бы помочь вам не только в анализе. - person Jon Skeet   schedule 08.06.2019LocalDateTime
— это неправильный класс для отслеживания момента, как объясняется в его Javadoc. Вместо этого используйтеInstant
,OffsetDateTime
иZonedDateTime
. - person Basil Bourque   schedule 08.06.2019