I have a String representing a date (with or without time) like 13/12/2017
or 13/12/2017 15:39:51
So i'm trying to use java 8 DateTimeFormatter with optional part.
That code works
LocalDateTime localDateTime = LocalDateTime.parse("13/12/2017 15:39:51",DateTimeFormatter.ofPattern("dd/MM/yyyy[ HH:mm:ss]"));
System.out.println(localDateTime.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")));
System.out.println(localDateTime.format(DateTimeFormatter.ofPattern("HH:mm:ss")));
13/12/2017
15:39:51
But I don't understand why that one does not
LocalDateTime localDateTime = LocalDateTime.parse("13/12/2017",DateTimeFormatter.ofPattern("dd/MM/yyyy[ HH:mm:ss]"));
giving me
Exception in thread "main" java.time.format.DateTimeParseException: Text '13/12/2017' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {},ISO resolved to 2017-12-13 of type java.time.format.Parsed
at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1920)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1855)
at java.time.LocalDateTime.parse(LocalDateTime.java:492)
...
And even with
LocalDateTime localDateTime = LocalDateTime.parse("13/12/2017",DateTimeFormatter.ofPattern("dd/MM/yyyy"));
it does not work with the same exception.
DateTimeFormatter is a replacement for the old SimpleDateFormat that is thread-safe and provides additional functionality.
A formatter created from a pattern can be used as many times as necessary, it is immutable and is thread-safe.
DateTimeFormatter fmt = DateTimeFormatter. ofPattern("yyyy-MM-dd'T'HH:mm:ss"); System. out. println(ldt.
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); System. out. println(sdf.
parseBest
When you use an optional component, you should parse using parseBest
. Your application may be working using only parse
, but then it's only by luck (because you're only parsing full inputs, not partial ones). With parseBest
, you can properly handle various TemporalAccessor
, which is the whole reason to use optional.
The decision of which TemporalAccessor
is returned is rather simple: parseBest
will try to match each TemporalQuery
in order of argument. When any matches, the method returns that one. So make sure to go from most precise to less precise. Also, if none were matched, an exception will be thrown.
LocalDateTime dateTime;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy[ HH:mm:ss]");
TemporalAccessor temporalAccessor = formatter.parseBest("13/12/2017", LocalDateTime::from, LocalDate::from);
if (temporalAccessor instanceof LocalDateTime) {
dateTime = (LocalDateTime)temporalAccessor;
} else {
dateTime = ((LocalDate)temporalAccessor).atStartOfDay();
}
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