Проблема с форматом даты с DateTimeFormatter [дубликат]
У меня есть дата в следующем формате: 1/1/2020 3:4:7 AMя пытаюсь отформатировать ее, используя DateTimeFormatter.
У меня есть следующий код с форматировщиком для его анализа, но он не работает.
LocalDateTime date = LocalDateTime.parse("1/1/2020 3:4:7 AM", DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss a"));
У меня следующее исключение:
java.time.format.DateTimeParseException: Text '1/1/2020 3:4:7 AM' could not be parsed at index 0
Может кто-нибудь мне помочь?
Ответы
Две отдельные проблемы:
Неправильный подсчет
Вы используете, например, MMкоторый является явным: Всегда полное количество цифр с нулями. Ваша строка не такая, это просто число. Итак, сделайте это M/d/uuuu h:m:s a.
РЕДАКТИРОВАТЬ: изменено yyyyна uuuu, спасибо, @deHaar. Обоснование: гггг или уууу редко имеют значение, но учтите, что это означает, что требуется 4 цифры . Разница проявляется за годы до 0: uuuuстановится отрицательной, yyyyнет и ожидает, что вы будете использовать, например, GGчтобы вы получили 44 BCвместо -44. Таким образом, uuuuэто просто более правильно, хотя обычно разница не возникает.
Отсутствует локаль
Вторая проблема заключается в том, что вам практически никогда не следует использовать эту версию ofPattern- в ней есть ошибка, которую вы не можете отловить с помощью модульных тестов, что делает эту ошибку в тысячи раз «тяжелее» и, таким образом, представляет собой настоящую проблему. .
Вам нужно указать локаль. Без него AM не будет анализировать, если локаль вашей платформы по умолчанию не является английской.
Собираем все вместе
LocalDateTime date = LocalDateTime.parse("1/1/2020 3:4:7 AM",
DateTimeFormatter.ofPattern("M/d/uuuu h:m:s a", Locale.ENGLISH));
работает отлично.
В вашем фрагменте:
LocalDateTime
.parse("1/1/2020 3:4:7 AM", DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss a"));
1- не соответствуетMM1- не соответствуетdd3- не соответствуетhh4- не соответствуетmm7- не соответствуетss
т.е. длины частей шаблона форматирования (например MM) и их соответствующих частей из текста строки (например 1) не совпадают.
Вы можете сопоставить их несколькими способами, например, вы можете либо изменить текст строки, чтобы он соответствовал шаблону форматирования, либо наоборот.
Вместо этого вы можете попробовать следующее:
LocalDateTime
.parse("01/01/2020 03:04:07 AM", DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss a"));
Кроме того, обратите внимание на буквы и символы образца .
Используйте отдельные буквы для компонентов даты и времени (месяц, день, год, час, минута и секунда).
Вы также можете заставить форматер обрабатывать шаблон без учета регистра (например, am, AM, Am), как показано ниже:
import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.util.Locale; public class Main { public static void main(String[] args) { // Formatter to handle the pattern in case insensitive way (e.g. am, AM, Am) DateTimeFormatter formatter = new DateTimeFormatterBuilder() .parseCaseInsensitive() .appendPattern("M/d/u h:m:s a") .toFormatter(Locale.ENGLISH); LocalDateTime date = LocalDateTime.parse("1/1/2020 3:4:7 AM", formatter); System.out.println(date); } }
Вывод:
2020-01-01T03:04:07
Согласно документации DateTimeFormatter :
Число: если количество букв равно единице , то значение выводится с использованием минимального количества цифр и без заполнения. В противном случае количество цифр используется в качестве ширины выходного поля, при необходимости значение дополняется нулями.
Изменив рассуждения, вы можете попробовать использовать вместо этого этот форматировщик:
DateTimeFormatter.ofPattern("M/d/yyyy h:m:s a")