0

I have input strings in nearly standard ISO 8601, but the minute-of-hour part is omitted (don't ask why, funky data feed out of my control).

2018-01-23T12

How do I parse that while letting the minute-of-hour default to zero?

2018-01-23T12:00

DateTimeFormatter.ISO_LOCAL_DATE_TIME

The default parser for LocalDateTime is DateTimeFormatter.ISO_LOCAL_DATE_TIME. This formatter tolerates optional second-of-minute. The fractional second and the second-of-minute are both set to zero.

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

But omitting the minute-of-hour fails, with exception thrown.

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

DateTimeFormatterBuilder

I am aware of the DateTimeFormatterBuilder class and its ability to tolerate optional parts while setting default values.

But I have been able to use it properly. I tried the pattern "uuuu-MM-dd HH" while setting both minute-of-hour and second-of-minute to default to zero.

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 );

Exception thrown:

Exception in thread "main" java.time.format.DateTimeParseException: Text '2018-01-23T12' could not be parsed at index 10

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

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

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

at com.basilbourque.example.App.doIt(App.java:31)

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

2
  • It's a bit hacky, but have you thought of +":00" to the end of the strings? Commented Mar 7, 2018 at 23:29
  • @Autumnal Yes, but… I'm really trying to learn more about how DateTimeFormatterBuilder works. In other words, I'm more interested in an education than a solution. This particular problem seemed like a good example for a Stack Overflow Question, as none of the other six Questions on DateTimeFormatterBuilder with "optional" or "default" cover this. Commented Mar 7, 2018 at 23:41

1 Answer 1

1

If you look carefully at the error message, you will see that it says: Text '2018-01-23T12' could not be parsed at index 10 This means that the problem is the T in the format.

If we then go back to the DateTimeFormatterBuilder, the pattern specified is: "uuuu-MM-dd HH". Here is the problem, this specifies a space when there is in fact a T. The solution is to replace this pattern with: "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

Indeed, you do not even need the builder at all. Specify a DateTimeFormatter with that same pattern. The minute-of-hour does default to zero.

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

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

2018-01-23T12:00

Sign up to request clarification or add additional context in comments.

1 Comment

Oh, whoops. In my experimenting, I messed that up. Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.