DateTimeParseException: Text '2019-06-07 12:18:16' could not be parsed
Asked Answered
A

1

-1

I have following code to convert an Instant to String then convert it back to I

String timestampString = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss"));
LOGGER.info("timestampString: " + timestampString);

Instant instant =
    LocalDateTime.parse(timestampString,
        DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss")).toInstant(ZoneOffset.UTC);

it print the timestampString as: 2019-06-07 12:45:57

and failed at parse the string:

java.time.format.DateTimeParseException: Text '2019-06-07 12:45:57' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {MinuteOfHour=45, HourOfAmPm=0, NanoOfSecond=0, SecondOfMinute=57, MilliOfSecond=0, MicroOfSecond=0},ISO resolved to 2019-06-07 of type java.time.format.Parsed

why it cannot parse it even though that's the same format I convert the timestamp to?

Analyse answered 7/6, 2019 at 19:49 Comment(5)
Possible duplicate of java.time.format.DateTimeParseException: Unable to obtain ZonedDateTime from TemporalAccessor on format ddMMyyyyhhmmss. And/or of Converting text to instant [duplicate].Unconstitutional
Tip: more tags will help attract more people who know about the subject that you’re asking about.Unconstitutional
Basically, you want HH rather than hh. hh is 12-hour hour of day; you want the 24-hour hour of day.Pyongyang
I do wonder why you're converting it to a string and back, mind you - note that LocalDateTime.now() uses the system time zone, whereas you're then claiming it's in UTC. If you could provide more context for what you're trying to achieve, we may be able to help you with more than the parsing.Pyongyang
LocalDateTime is the wrong class to track a moment, as explained in its Javadoc. Use Instant, OffsetDateTime, and ZonedDateTime instead.Arnulfo
U
2

Use HH for hour of day instead of hh

The problem that you are asking about is that you are using lowercase hh in your format pattern string (both times). You need uppercase HH for hour day from 00 through 23. hh is for hour within AM or PM from 01 through 12. So what went wrong was that java.time didn’t know whether 12 in your string referred to 12 AM or 12 PM and refused to make a guess for you.

If you read the exception message closely you will also notice that it says that HourOfAmPm=0 was parsed. It doesn’t say HourOfDay.

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    String timestampString = LocalDateTime.now().format(formatter);
    System.out.println("timestampString: " + timestampString);

    Instant instant = LocalDateTime.parse(timestampString, formatter)
            .toInstant(ZoneOffset.UTC);

    System.out.println("instant: " + instant);

When I ran this snippet just now, I got this output:

timestampString: 2019-06-08 19:22:51
instant: 2019-06-08T19:22:51Z

This is wrong! I ran the snippet around 17:22 UTC, not 19:22. Since Denmark is still using summer time (damn), the local time here was 19:22, which was used for the result and translated into the same wall clock time in UTC, not the same instant. You should always pass your desired time zone to the now method to avoid such bugs. Since you wanted UTC:

    String timestampString = LocalDateTime.now(ZoneOffset.UTC).format(formatter);
timestampString: 2019-06-08 17:27:57
instant: 2019-06-08T17:27:57Z

Still better, don’t use LocalDateTime for holding something that you want to use as a moment in time. Use Instant, OffsetDateTime or ZonedDateTime instead.

There is more information on using hh, HH or kk for formatting and parsing hour values in this question and its answers: Difference between java HH:mm and hh:mm on SimpleDateFormat. The question is asking about the notoriously troublesome SimpleDateFormat, but the answers are valid for DateTimeFormatter too.

Unconstitutional answered 8/6, 2019 at 17:29 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.