I am trying to parse a date time with Instant.parse() with time zone offset. I read the documentation and it said I must do that using the ISO-8601. I read the Wikipedia's ISO-8601 article and I copied this date time "2007-11-03T13:18:05-03:00" from there, and I used it with the parse() method. The call throw an exception, saying that the argument could not be parsed. I don't understand why is that happening. Could somebody help me?
-
Add your code, we can help from there. – stringy05 Jul 01 '21 at 22:44
-
4`Instant` only supports UTC, it doesn't support offset. For that, use `OffsetDateTime`. You can then convert the `Instant`, which will correctly adjust the time by the offset to get the UTC time: `System.out.println(OffsetDateTime.parse("2007-11-03T13:18:05-03:00").toInstant())` prints `2007-11-03T16:18:05Z`. – Andreas Jul 01 '21 at 23:31
-
1@Andreas You don't need to go through OffsetDateTime when you want an Instant in UTC, parsing the String with offset is fine for Instant: https://ideone.com/ddV3ve – Tom Jul 02 '21 at 09:24
-
@Tom Nice observation. Do you know since which Java version that is? I’m convinced that that didn’t work in Java 8 (where `Instant` and java.time were introduced). – Ole V.V. Jul 02 '21 at 10:36
-
Java 12 is the first version where I find information in the documentation that other offsets than `Z` are accepted for parsing. @Tom – Ole V.V. Jul 02 '21 at 11:31
-
@OleV.V. Ideone is inable to properly communicate which Java version it actually uses. It only offers one version, Java 1.8, but in the original link it says on the right sidebar Version 12. When I re-select the only Java version it offers, then it says Java 1.8 (https://ideone.com/FSQHPl). So I can't tell for sure. – Tom Jul 02 '21 at 12:36
-
1@Tom To determine the version of Java used by IdeOne.com, add a call to [`Runtime.version()`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Runtime.html#version()) (a method added to Java 9+). [See for yourself](https://ideone.com/TENZVb). Today I get: 12.0.1+12 – Basil Bourque Jul 02 '21 at 15:48
-
@BasilBourque Good idea and ideone actually offers two versions. The one listed under "popular" is Java 12 and the one listed under "others" is Java 8. It also turns out that the code in my second comment says it uses Java 8, but actually runs on Java 12 https://ideone.com/8cq57C. This is really weird, because even if it would just set the language level to Java 8, then `Runtime.version()` shouldn't work anymore, because that came with Java 9. – Tom Jul 02 '21 at 15:59
2 Answers
Edit: As @Tom noted in a comment, since Java 12 we can simply do:
System.out.println(Instant.parse("2007-11-03T13:18:05-03:00"));
Output is:
2007-11-03T16:18:05Z
Original answer: another option (for Java versions up to 11) is:
Instant yourInstant = DateTimeFormatter.ISO_OFFSET_DATE_TIME
.parse("2007-11-03T13:18:05-03:00", Instant::from);
System.out.println(yourInstant);
Output is the same as above.
Which to prefer? I think it’s a matter of taste.

- 81,772
- 15
- 137
- 161
tl;dr
OffsetDateTime
.parse(
"2007-11-03T13:18:05-03:00"
)
.toInstant()
.toString()
Details
The -03:00
at the end of your string "2007-11-03T13:18:05-03:00"
means an offset of three hours behind UTC.
The Instant
class represents a moment seen at UTC, an offset of zero hours-minutes-seconds.
Use OffsetDateTime
class instead.
OffsetDateTime odt = OffsetDateTime.parse( "2007-11-03T13:18:05-03:00" ) ;
To adjust to an offset of zero, extract an Instant
.
Instant instant = odt.toInstant() ;
To generate a string with text in standard ISO 8601 format, call toString()
.
String output = instant.toString() ;
For date-time values with a time zone rather than a mere offset, use ZonedDateTime
class.
For only a date and time-of-day but lacking the context of an offset or zone, use LocalDateTime
.

- 19,142
- 7
- 29
- 41

- 303,325
- 100
- 852
- 1,154