Java parsing String to LocalDateTime without providing time
date, datetime, java
Solution
Your issue is that a LocalDateTime needs a time!
You have two main options:
- use two formatters like you do, but the second branch should be `LocalDateTime d = LocalDate.parse(value, formatter).atStartOfDay()` (for example)
- create a formatter that can handle both formats
The second option could look like:
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd")
.optionalStart()
.appendPattern(" HH:mm")
.optionalEnd()
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.toFormatter();
which can parse `2016-10-01` and `2016-10-01 10:15`.
Problem
Basically I have a field ``` private LocalDateTime date; ``` which is parsed from String. It works fine when provided String has time appended at the end but will throw an exception if it has not. ``` DateTimeFormatter formatter = null; if (value.matches("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}")) { formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); } else if (value.matches("\\d{4}-\\d{2}-\\d{2}")) { formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); } // Throws an exception for pattern "yyyy-MM-dd" date = LocalDateTime.parse(value, formatter); ``` And the exception itself: ``` java.time.format.DateTimeParseException: Text '2000-06-29' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {},ISO resolved to 2000-06-29 of type java.time.format.Parsed at pl.empirica.swissborg.service.util.CsvBeanUtils.copyList(CsvBeanUtils.java:75) ~[classes/:na] at pl.empirica.swissborg.service.csv.CsvReaderService.persistCsvData(CsvReaderService.java:101) ~[classes/:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_91] at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_91] at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_91] at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_91] at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:354) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE] at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:305) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE] at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:133) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE] ... 18 common frames omitted Caused by: java.lang.RuntimeException: java.time.format.DateTimeParseException: Text '2000-06-29' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {},ISO resolved to 2000-06-29 of type java.time.format.Parsed at pl.empirica.swissborg.service.util.CsvBeanUtils.copyFields(CsvBeanUtils.java:58) ~[classes/:na] at pl.empirica.swissborg.service.util.CsvBeanUtils.copyList(CsvBeanUtils.java:70) ~[classes/:na] ... 26 common frames omitted Caused by: java.time.format.DateTimeParseException: Text '2000-06-29' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {},ISO resolved to 2000-06-29 of type java.time.format.Parsed at java.time.format.DateTimeFormatter.createError(Unknown Source) ~[na:1.8.0_91] at java.time.format.DateTimeFormatter.parse(Unknown Source) ~[na:1.8.0_91] at java.time.LocalDateTime.parse(Unknown Source) ~[na:1.8.0_91] at pl.empirica.swissborg.service.util.CsvBeanUtils.copyFields(CsvBeanUtils.java:47) ~[classes/:na] ... 27 common frames omitted Caused by: java.time.DateTimeException: Unable to obtain LocalDateTime from TemporalAccessor: {},ISO resolved to 2000-06-29 of type java.time.format.Parsed at java.time.LocalDateTime.from(Unknown Source) ~[na:1.8.0_91] at java.time.format.Parsed.query(Unknown Source) ~[na:1.8.0_91] ... 30 common frames omitted Caused by: java.time.DateTimeException: Unable to obtain LocalTime from TemporalAccessor: {},ISO resolved to 2000-06-29 of type java.time.format.Parsed at java.time.LocalTime.from(Unknown Source) ~[na:1.8.0_91] ... 32 common frames omitted ``` EDIT: for clarification, I'm 100% certain that formatter is set by the 2nd conditional branch.