Проблема с анализом LocalDateTime с использованием Java 8

У меня есть этот код, это простая строка, которую я хочу разобрать на LocalDateTime

    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    import java.time.format.DateTimeFormatterBuilder;

    public class DateClass {

        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {

            String dateRaw = "2019-05-03 7:05:03";        

            DateTimeFormatter dtf = new DateTimeFormatterBuilder().appendPattern("uuuu-mm-dd HH:mm:ss").toFormatter(); 

            LocalDateTime date= LocalDateTime.parse(dateRaw, dtf);
            System.out.println(date.toString());
        }

    }

И когда я запускаю, у меня есть следующая ошибка:

Exception in thread "main" java.time.format.DateTimeParseException: Text '2019-05-03 7:05:03' could not be parsed at index 11
    at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
    at java.time.LocalDateTime.parse(LocalDateTime.java:492)
    at lectordeachvio.DateClass.main(DateClass.java:18)

что я делаю не так? а почему лох с де космосом????


person Alberto D    schedule 16.11.2019    source источник
comment
ЧЧ будет 07, но почему вы используете минуты дважды?   -  person OneCricketeer    schedule 16.11.2019
comment
Попробуйте использовать «2019-05-03 07:05:03» в качестве шаблона даты.   -  person newOne    schedule 16.11.2019
comment
Прописная буква M для месяца и y для года   -  person Jens    schedule 16.11.2019
comment
@Jens Строго говоря, y не год. u для (подписанного) года. y - год эры. См. uuuu по сравнению с yyyy в кодах шаблонов форматирования DateTimeFormatter в Java?   -  person Ole V.V.    schedule 16.11.2019
comment
Это хороший вопрос. Думаю, ожидаемый результат ясен, и вопрос уже минимален. воспроизводимый пример и конкретная проблема в виде хорошо отформатированной трассировки стека. Молодец, новый укладчик. Также я думаю, что этот вопрос может быть полезен для многих будущих читателей (если они смогут его найти, я признаю, что это может быть трудно найти).   -  person Ole V.V.    schedule 16.11.2019


Ответы (2)


    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd H:mm:ss");

С этим изменением ваша программа выводит:

2019-05-03T07:05:03

  • Буква шаблона единого формата H будет соответствовать часу дня либо одной, либо двумя цифрами. То есть он будет принимать 7, 07, 13 и т. д. С другой стороны, два HH требуют двух цифр, таких как 07 или 13, поэтому 7 нельзя проанализировать отдельно. Это было причиной исключения, которое вы получили.
  • Индекс 11 вашей строки не там, где есть пробел. Здесь находится 7. Индексы отсчитываются от 0.
  • Как уже упоминалось, вам также необходимо использовать верхний регистр MM для номера месяца. mm в нижнем регистре обозначает минуты часа.
  • Кроме того, в этом случае вам не обязательно нужен DateTimeFormatterBuilder. DateTimeFormatter.ofPattern работает нормально.

Просто из любопытства, если ваш форматтер предназначен только для синтаксического анализа, вы можете опустить все повторения букв шаблона. Это тоже работает:

    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("u-M-d H:m:s");

Хотя обычно мы бы этого не хотели. Мы бы предпочли проверить наличие двухзначных минут и секунд, часто также для обозначения месяца и дня месяца. Ввод двух букв шаблона достигает этого.

Частично связанный вопрос о mm в шаблоне формата: Convert LocalDate в DD/MM/YYYY LocalDate [дубликат].

person Ole V.V.    schedule 16.11.2019
comment
Большое спасибо, всем вам и особенно вам Оле.В.В. он работает, как вы сказали, String dateRaw = 2019-05-03 7:05:03; DateTimeFormatter dtf = new DateTimeFormatterBuilder().appendPattern(uuuu-MM-dd H:mm:ss).toFormatter(); Используя это: DateTimeFormatter dtf = DateTimeFormatter.ofPattern(u-M-d H:m:s); у меня ошибка - person Alberto D; 19.11.2019
comment
вот правильный код: public class DateClass { public static void main(String[] args) { String dateRaw = "2019-05-03 12:05:03"; DateTimeFormatter dtf = new DateTimeFormatterBuilder().appendPattern("uuuu-MM-dd H:mm:ss").toFormatter(); LocalDateTime date= LocalDateTime.parse(dateRaw, dtf); System.out.println("LocalDatetime ->"+date.toString()); try { Date date1 = new SimpleDateFormat("yyyy-MM-dd H:mm:ss").parse(dateRaw); System.out.println("Date ->"+ date1); }catch(Exception e){}}} - person Alberto D; 22.11.2019
comment
Спасибо за публикацию вашего кода. Пожалуйста, ради вашего же блага, не связывайтесь с классом SimpleDateFormat, это известный нарушитель спокойствия. А java,time дает вам всю необходимую функциональность и многое другое. И не «проглатывайте исключения»: пустой блок catch — это nono, он скроет от вас ошибки, так что это все равно, что программировать с завязанными глазами. - person Ole V.V.; 08.12.2019

Вы должны изменить свой шаблон в отношении месяца, потому что вы используете минуты:

"уууу-ММ-дд ЧЧ:мм:сс"

См. документы. И измените часовую часть даты в примере с 7 на 07, как указано в шаблоне.

person newOne    schedule 16.11.2019
comment
Изменить дату или шаблон? - person Jens; 16.11.2019
comment
Также я думаю, что на SO есть дубликаты, поэтому вы должны связать zehn, а не писать новый ответ. - person Jens; 16.11.2019
comment
@Jens Ты легко можешь быть прав насчет обмана, так что если ты сможешь найти оригинал? Я не нашел (пока). - person Ole V.V.; 17.11.2019