I am trying to parse the date using LocalDateTime.parse
the method however I am getting below error. the date string is getting parse if I use SimpleDateFormat
simple date format object.
Has anyone faced this issue! What's the difference between parse from DateFormat
and LocalDateTime
package com.example.demo;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
public class App {
public static final String DATE_TIME_PATTERN = "dd-MM-yyyy hh:mm:ss.SSS";
public static final DateFormat DATE_TIME_FORMAT = new SimpleDateFormat(DATE_TIME_PATTERN);
public static final String SEPERATOR = ",";
public static void main(String[] args) {
try {
Date date = DATE_TIME_FORMAT.parse("12-03-2019 10:28:50.013");
System.out.println("date : {} " + date);
LocalDateTime startTimestamp = LocalDateTime.parse("12-03-2019 10:28:50.013", DateTimeFormatter.ofPattern(DATE_TIME_PATTERN)).plusNanos(1000000);
System.out.println("startTimestamp : {} " + startTimestamp);
} catch(Exception e) {
e.printStackTrace();
}
}
}
OUTPUT
date : {} Tue Mar 12 10:28:50 SGT 2019
java.time.format.DateTimeParseException: Text '12-03-2019 10:28:50.013' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {NanoOfSecond=13000000, HourOfAmPm=10, MicroOfSecond=13000, SecondOfMinute=50, MilliOfSecond=13, MinuteOfHour=28},ISO resolved to 2019-03-12 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)
at com.example.demo.App.main(App.java:21)
Caused by: java.time.DateTimeException: Unable to obtain LocalDateTime from TemporalAccessor: {NanoOfSecond=13000000, HourOfAmPm=10, MicroOfSecond=13000, SecondOfMinute=50, MilliOfSecond=13, MinuteOfHour=28},ISO resolved to 2019-03-12 of type java.time.format.Parsed
at java.time.LocalDateTime.from(LocalDateTime.java:461)
at java.time.format.Parsed.query(Parsed.java:226)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
... 2 more
Caused by: java.time.DateTimeException: Unable to obtain LocalTime from TemporalAccessor: {NanoOfSecond=13000000, HourOfAmPm=10, MicroOfSecond=13000, SecondOfMinute=50, MilliOfSecond=13, MinuteOfHour=28},ISO resolved to 2019-03-12 of type java.time.format.Parsed
at java.time.LocalTime.from(LocalTime.java:409)
at java.time.LocalDateTime.from(LocalDateTime.java:457)
... 4 more
The java SimpleDateFormat allows construction of arbitrary non-localized formats. The java DateFormat allows construction of three localized formats each for dates and times, via its factory methods.
SimpleDateFormat is a concrete class for formatting and parsing dates in a locale-sensitive manner. It allows for formatting (date -> text), parsing (text -> date), and normalization. SimpleDateFormat allows you to start by choosing any user-defined patterns for date-time formatting.
DateTimeFormatter is a replacement for the old SimpleDateFormat that is thread-safe and provides additional functionality.
SimpleDateFormat format() Method in Java with Examples Return Value: The method returns Date or time in string format of mm/dd/yyyy.
You are using the clock-hour-of-am-pm (1-12) for hour which is h
in your pattern and not hour-of-day (0-23) which is H
, so it needs the additional info of the AM/PM.
So ideally the AM/PM must be mentioned in the date string which is to be parsed along with a
for am-pm-of-day which also needs to be added in the DATE_TIME_PATTERN
String.
public static final String DATE_TIME_PATTERN = "dd-MM-yyyy hh:mm:ss.SSS a";
public static final DateFormat DATE_TIME_FORMAT = new SimpleDateFormat(DATE_TIME_PATTERN);
public static final String SEPERATOR = ",";
public static void main(String[] args) {
try {
Date date = DATE_TIME_FORMAT.parse("12-03-2019 10:28:50.013 AM");
System.out.println("date : {} " + date);
LocalDateTime startTimestamp = LocalDateTime.parse("12-03-2019 10:28:50.013 AM", DateTimeFormatter.ofPattern(DATE_TIME_PATTERN)).plusNanos(1000000);
System.out.println("startTimestamp : {} " + startTimestamp);
} catch(Exception e) {
e.printStackTrace();
}
}
Output:
date : {} Tue Mar 12 10:28:50 IST 2019
startTimestamp : {} 2019-03-12T10:28:50.014
We can see that without the proper format SimpleDateFormat
is working while LocalDateTime
is more stricter when it comes to parsing invalid date strings. In your case since the required AM/PM info is missing, the LocalTime
returned from the TemporalAccessor
is null
and hence you are getting Unable to obtain LocalTime from TemporalAccessor
.
No coming to why SimpleDateFormat
is working, there is a method called setLenient(boolean lenient)
if you pass hour which is greater than 12
without mentioning a
in the pattern and AM/PM in the date string an java.text.ParseException: Unparseable date:
will be thrown.
But since in your case you are passing the hour as 10
this is less than 12
and hence it is interpreted as AM by default.
This is the code in SimpleDateFormat class where this checking is happening:
case PATTERN_HOUR1: // 'h' 1-based. eg, 11PM + 1 hour =>> 12 AM
if (!isLenient()) {
// Validate the hour value in non-lenient
if (value < 1 || value > 12) {
break parsing;
}
}
// [We computed 'value' above.]
if (value == calendar.getLeastMaximum(Calendar.HOUR) + 1) {
value = 0;
}
calb.set(Calendar.HOUR, value);
return pos.index;
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