Instant.parse and RFC3339 string throws java.time.format.DateTimeParseException
Asked Answered
T

3

8

If I do

import java.time.Instant;
...
    Instant instant = Instant.parse("2018-01-02T18:14:59.000+01:00")

I get this exception:

Caused by: java.time.format.DateTimeParseException: Text '2018-06-19T23:00:00.000+01:00' could not be parsed at index 23
    at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1777)

But if I do

    Instant instant = Instant.parse("2018-06-19T23:00:00.000Z");

All works fine.

What do I miss? Whats wrong with the first time string?

Thuythuya answered 11/7, 2018 at 12:2 Comment(3)
The string must represent a valid instant in UTC that is probalby the reason your first example doesnt workDuchamp
Why -1? At least comment, what shold be wrong...Thuythuya
I think you got downote, becuse this is related to "why is this code not working" and the solution can be easily found by just reading the doc of the used method ;)Dorsad
D
6

The reason is that your first String does not match the acceptable format for parse method


As the doc states for Instant#parse(CharSequence text) :

The string must represent a valid instant in UTC and is parsed using DateTimeFormatter.ISO_INSTANT

And the doc for DateTimeFormatter#ISO_INSTANT states :

The ISO instant formatter that formats or parses an instant in UTC, such as '2011-12-03T10:15:30Z'.


To get an Instant from you string you need : Workable Demo

String str = "2018-01-02T18:14:59.000+01:00";
Instant instant = DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(str, Instant::from);
Dorsad answered 11/7, 2018 at 12:10 Comment(1)
That is not the question sure, I would also have marked it as correct answer (but I was not able because it can not be immediately marked, sorry).Thuythuya
S
3

Your date string contains zone information. ISO_INSTANT (default format for Instant::parse method) does not handle this. Instead use

Instant instant = DateTimeFormatter.ISO_ZONED_DATE_TIME.parse(date, Instant::from);
Sandor answered 11/7, 2018 at 12:15 Comment(0)
H
1

Now JDK 12 and higher can parse it, while JDK <= 11 can't. The Java 12 Javadoc of DateTimeFormatter.ISO_INSTANT added the following new sentence:

When parsing, the behaviour of DateTimeFormatterBuilder.appendOffsetId() will be used to parse the offset, converting the instant to UTC as necessary.

Indeed, the corresponding JDK bug (JDK-8166138) shows that the fix is available starting from Java 12.

For example (from here),

$ docker run --rm -it openjdk:14-jdk
Apr 27, 2020 2:28:44 PM java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.
|  Welcome to JShell -- Version 14.0.1
|  For an introduction type: /help intro

jshell> java.time.Instant.parse("2020-04-21T13:22:10.836777828-07:00");
$1 ==> 2020-04-21T20:22:10.836777828Z

jshell> 
Heartsease answered 27/4, 2020 at 18:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.