Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
809 views
in Technique[技术] by (71.8m points)

time - Java 8 DateTimeFormatter with optional part

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Use 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();
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...