Fixing Java DateTimeParseException with LocalDateTime
When working with Java’s java.time
package, we sometimes encounter the DateTimeParseException
with the message:
“Unable to obtain LocalDateTime from TemporalAccessor”.
This error can be confusing, especially when the input string appears valid. This article will explore why this exception occurs and effective strategies to fix and prevent it.
1. Root Cause: Missing Time Component
The most common cause is attempting to parse a date-only string into a LocalDateTime
, which requires both date and time components.
Example That Fails
import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class DateTimeExample { public static void main(String[] args) { String input = "2024-12-25"; // Only date, no time DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); LocalDateTime dateTime = LocalDateTime.parse(input, formatter); // Exception System.out.println(dateTime); } }
Output:
Exception in thread "main" java.time.format.DateTimeParseException: Text '2024-12-25' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {},ISO resolved to 2024-12-25 of type java.time.format.Parsed at java.base/java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:2079) at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:2014) at java.base/java.time.LocalDateTime.parse(LocalDateTime.java:494) at com.jcg.examples.DateTimeExample.main(DateTimeExample.java:20) Caused by: java.time.DateTimeException: Unable to obtain LocalDateTime from TemporalAccessor: {},ISO resolved to 2024-12-25 of type java.time.format.Parsed at java.base/java.time.LocalDateTime.from(LocalDateTime.java:463) at java.base/java.time.format.Parsed.query(Parsed.java:247) at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:2010) ... 2 more Caused by: java.time.DateTimeException: Unable to obtain LocalTime from TemporalAccessor: {},ISO resolved to 2024-12-25 of type java.time.format.Parsed at java.base/java.time.LocalTime.from(LocalTime.java:441) at java.base/java.time.LocalDateTime.from(LocalDateTime.java:459)
What Does the Exception Mean?
This means that:
- The input string was parsed, but
- The parser could not extract enough information to create a
LocalDateTime
object.
Java uses the TemporalAccessor
interface to represent partially parsed date-time information. If this information is insufficient to construct a specific date-time type like LocalDateTime
, the exception is thrown.
2. Use LocalDate
Instead
To resolve this, we should use LocalDate
if our input string contains only a date and no time. LocalDate
is specifically designed to handle date-only values.
public static void main(String[] args) { String input = "2024-12-25"; DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); LocalDate date = LocalDate.parse(input, formatter); // Correct System.out.println(date); // 2024-12-25 }
In this example:
- The input string
"2024-12-25"
contains only the date, without any time component. - A
DateTimeFormatter
is used to match the pattern of the input string ("yyyy-MM-dd"
). - Instead of using
LocalDateTime
, we correctly parse it into aLocalDate
, which succeeds without errors.
By using LocalDate
, the code avoids the need to obtain a time component from the parsed result, which is precisely what causes the exception when trying to parse into LocalDateTime
.
3. Use LocalDate.parse()
with a Built-in Formatter
When parsing a date-only string, it is often helpful to utilize the built-in ISO_LOCAL_DATE
formatter, which simplifies the parsing process. This formatter is designed for strings that follow the ISO-8601 standard (yyyy-MM-dd
). Using this formatter avoids the need to manually define a custom pattern and ensures that the date is parsed correctly into a LocalDate
.
String input = "2024-12-25"; LocalDate date = LocalDate.parse(input, DateTimeFormatter.ISO_LOCAL_DATE); // Correct System.out.println(date); // 2024-12-25
Here, we use LocalDate.parse()
with DateTimeFormatter.ISO_LOCAL_DATE
, which is the standard ISO-8601 date format (yyyy-MM-dd
).
Alternatively, if we require a LocalDateTime
instead of just a LocalDate
, and the input string includes both date and time components in ISO-8601 format (yyyy-MM-dd'T'HH:mm:ss
), we can use LocalDateTime.parse()
along with the built-in DateTimeFormatter.ISO_LOCAL_DATE_TIME
.
String input = "2024-12-25T14:30:00"; LocalDateTime dateTime = LocalDateTime.parse(input, DateTimeFormatter.ISO_LOCAL_DATE_TIME); System.out.println(dateTime); // 2024-12-25T14:30
Here, we use LocalDateTime.parse()
with the built-in DateTimeFormatter.ISO_LOCAL_DATE_TIME
, which correctly interprets the format. This results in a properly parsed LocalDateTime
object that contains both the date and time.
4. Append Default Time If Missing
4.1 Use LocalDate.parse(...).atStartOfDay()
Another practical solution is to first parse the string into a LocalDate
and then convert it to a LocalDateTime
using the .atStartOfDay()
method. This method sets the time to midnight (00:00
) on the given date, effectively creating a valid LocalDateTime
without throwing a DateTimeParseException
.
String input = "2024-12-25"; DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); LocalDateTime dateTime = LocalDate.parse(input, formatter).atStartOfDay(); System.out.println(dateTime); // 2024-12-25T00:00
This example code parses the input into a LocalDate using LocalDate.parse(…), which succeeds, and then converts it into a LocalDateTime
with a time of 00:00
by calling .atStartOfDay()
.
4.2 Appending Time Manually
If the input string sometimes lacks the time, we can handle it by appending a default time before parsing.
String dateOnlyInput = "2024-12-25"; String fullInput = dateOnlyInput + " 00:00"; // default to midnight DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); LocalDateTime dateTime = LocalDateTime.parse(fullInput, formatter); // Works System.out.println(dateTime); // 2024-12-25T00:00
Appending a default time ensures that the string matches the expected format for LocalDateTime
. This is useful in systems where time might be optional.
5. Final Tips to Prevent the Exception
- Use
.atStartOfDay()
when converting fromLocalDate
toLocalDateTime
. - Always match the formatter to the input format.
- Use the correct date-time type:
LocalDate
,LocalTime
,LocalDateTime
, orZonedDateTime
. - Use
DateTimeFormatter.ISO_LOCAL_DATE
,ISO_LOCAL_DATE_TIME
, etc. when possible. They are robust and well-tested.
6. Conclusion
In this article, we explored the causes and solutions for the DateTimeParseException: Unable to obtain LocalDateTime from TemporalAccessor
in Java. This exception typically arises when attempting to parse a date-only string into a LocalDateTime
, which expects both date and time components. We demonstrated how to correctly handle such scenarios by using LocalDate
for date-only strings, converting to LocalDateTime
with .atStartOfDay()
when needed, and leveraging built-in formatters like DateTimeFormatter.ISO_LOCAL_DATE
and ISO_LOCAL_DATE_TIME
for ISO-standard inputs.
7. Download the Source Code
This article covered the Java DateTimeParseException related to LocalDateTime and TemporalAccessor, explaining its causes and solutions.
You can download the full source code of this example here: java datetimeparseexception localdatetime temporalaccessor