I'd like to parse '2015-10-01' with LocalDateTime
. What I have to do is
LocalDate localDate = LocalDate.parse('2015-10-01');
LocalDateTime localDateTime = localDateTime.of(localDate, LocalTime.MIN);
But I'd like to parse it in one pass like
// throws DateTimeParseException
LocalDateTime date = LocalDateTime.parse('2015-10-01', DateTimeFormatter.ISO_LOCAL_DATE);
Also a small difference of a string throws the exception as well.
// throws DateTimeParseException
LocalDate localDate = LocalDate.parse("2015-9-5", DateTimeFormatter.ISO_LOCAL_DATE);
Can I parse date strings leniently with Java 8 Date APIs?
If you want to parse date String as "2015-10-01"
and "2015-9-5"
to LocalDateTime
objects, you can build your own DateTimeFormatter
using DateTimeFormatterBuilder
:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("yyyy")
.appendLiteral('-')
.appendValue(MONTH_OF_YEAR)
.appendLiteral('-')
.appendValue(DAY_OF_MONTH)
.parseDefaulting(HOUR_OF_DAY, HOUR_OF_DAY.range().getMinimum())
.parseDefaulting(MINUTE_OF_HOUR, MINUTE_OF_HOUR.range().getMinimum())
.parseDefaulting(SECOND_OF_MINUTE, SECOND_OF_MINUTE.range().getMinimum())
.parseDefaulting(NANO_OF_SECOND, NANO_OF_SECOND.range().getMinimum())
.toFormatter();
System.out.println(LocalDateTime.parse("2015-9-5", formatter));
System.out.println(LocalDateTime.parse("2015-10-01", formatter));
The variable length of each field is handled by the call to appendValue(field)
. Quoting the Javadoc:
The parser for a variable width value such as this normally behaves greedily, requiring one digit, but accepting as many digits as possible.
This means that it will be able to parse month and days formatted with 1 or 2 digits.
To construct a LocalDateTime
, we also need to provide a LocalTime
to this builder. This is done by using parseDefaulting(field, value)
for each field of a LocalTime
. This method takes a field and a default value for that field if it is not present in the String to parse. Since, in our case, the time information will not be present in the String, the default values will be chosen, i.e. the minimum value for the range of valid values for that field (it is obtained by calling getMinimum
to the ValueRange
of that field; perhaps we could also hard-code 0 here).
In the event that the String to parse might contain time information, we can use optional sections of DateTimeFormatter
, like this:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("yyyy")
.appendLiteral('-')
.appendValue(MONTH_OF_YEAR)
.appendLiteral('-')
.appendValue(DAY_OF_MONTH)
.appendPattern("[ HH:mm]") // optional sections are surrounded by []
.parseDefaulting(HOUR_OF_DAY, HOUR_OF_DAY.range().getMinimum())
.parseDefaulting(MINUTE_OF_HOUR, MINUTE_OF_HOUR.range().getMinimum())
.parseDefaulting(SECOND_OF_MINUTE, SECOND_OF_MINUTE.range().getMinimum())
.parseDefaulting(NANO_OF_SECOND, NANO_OF_SECOND.range().getMinimum())
.toFormatter();
System.out.println(LocalDateTime.parse("2015-9-5", formatter));
System.out.println(LocalDateTime.parse("2015-10-01", formatter));
System.out.println(LocalDateTime.parse("2015-1-1 10:10", formatter));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With