Разбор строки ввода даты и времени с пропущенными минутами с использованием классов java.time

У меня есть входные строки в почти стандартном стандарте ISO 8601, но минутная часть не указана (не спрашивайте, почему, из-за моего контроля, шутливая подача данных).

2018-01-23T12

Как мне разобрать это, позволяя минутному значению по умолчанию обнуляться?

2018-01-23T12: 00

DateTimeFormatter.ISO_LOCAL_DATE_TIME

Парсер по умолчанию для LocalDateTime является DateTimeFormatter.ISO_LOCAL_DATE_TIME, Этот форматер допускает необязательную секунду минуты. Дробная секунда и секунда минуты установлены на ноль.

LocalDateTime ldt = LocalDateTime.parse( "2018-01-23T12:00" ) ;  // Works.

Но пропустить минуту не получится, за исключением брошенного исключения.

LocalDateTime ldt = LocalDateTime.parse( "2018-01-23T12" ) ;  // Fails.

DateTimeFormatterBuilder

Я знаю о DateTimeFormatterBuilder класс и его способность допускать необязательные части при установке значений по умолчанию.

Но я смог правильно его использовать. Я попробовал шаблон "uuuu-MM-dd HH" при установке минут и часов и секунд по умолчанию на ноль.

String input = "2018-01-23T12";

DateTimeFormatterBuilder b = new DateTimeFormatterBuilder().parseDefaulting( ChronoField.MINUTE_OF_HOUR , 0 ).parseDefaulting( ChronoField.SECOND_OF_MINUTE , 0 ).appendPattern( "uuuu-MM-dd HH" );
DateTimeFormatter f = b.toFormatter( Locale.US );
LocalDateTime ldt = LocalDateTime.parse( input , f );
System.out.println( ldt );

Исключение:

Исключение в потоке "main" java.time.format.DateTimeParseException: текст '2018-01-23T12' не может быть проанализирован с индексом 10

в java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1988)

в java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1890)

в java.base/java.time.LocalDateTime.parse(LocalDateTime.java:492)

на com.basilbourque.example.App.doIt(App.java:31)

в com.basilbourque.example.App.main(App.java:22)

1 ответ

Решение

Если вы внимательно посмотрите на сообщение об ошибке, вы увидите, что оно говорит: Text '2018-01-23T12' could not be parsed at index 10Это означает, что проблема в T в формате.

Если мы тогда вернемся к DateTimeFormatterBuilderуказанный шаблон: "uuuu-MM-dd HH", Вот проблема, это указывает пробел, когда на самом деле есть T. Решение состоит в том, чтобы заменить этот шаблон на: "uuuu-MM-dd'T'HH"

String input = "2018-01-23T12";

DateTimeFormatterBuilder b = new DateTimeFormatterBuilder().parseDefaulting( ChronoField.MINUTE_OF_HOUR , 0 ).parseDefaulting( ChronoField.SECOND_OF_MINUTE , 0 ).appendPattern( "uuuu-MM-dd'T'HH" );
DateTimeFormatter f = b.toFormatter( Locale.US );
LocalDateTime ldt = LocalDateTime.parse( input , f );
System.out.println( ldt );

2018-01-23T12:00

Действительно, вам даже не нужен строитель вообще. Укажите DateTimeFormatter с тем же рисунком. Минута часа по умолчанию равна нулю.

String input = "2018-01-23T12";

DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd'T'HH" ) ;
LocalDateTime ldt = LocalDateTime.parse( input , f );

2018-01-23T12:00

Другие вопросы по тегам