Java 8 DateTimeFormatter with optional part

I have a string representing a date (with or without time), e.g. 13/12/2017 or 13/12/2017 15:39:51

So, I'm trying to use java 8 DateTimeFormatter with an extra part.

This 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 do not understand why it is 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.

+5
source share
1 answer

Use parseBest

When you use an add-on component, you should parseBest using parseBest . An application can only work with parse , but then it is only luck (because you only process full inputs, not partial ones). With parseBest you can correctly handle various TemporalAccessor , which is the main reason for using optional.

The solution from which TemporalAccessor returns is pretty simple: parseBest will try to match each TemporalQuery in argument order. If there are any matches, the method returns this. Therefore, do not forget to switch from the most accurate to the less accurate. In addition, if none of them has been 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(); } 
+7
source

Source: https://habr.com/ru/post/1274731/


All Articles