1

I have a list of ISO 8601 date strings that I want to parse and convert to OffsetDateTime.

Below is how I am converting:

var date = OffsetDateTime.parse("2013-03-13T20:59:31-08:00");

This works totally fine but there are some dates in the list that don't have : in the Zone offset, therefore, I am getting the following exception from the parser.

var date = OffsetDateTime.parse("2013-03-13T20:59:31-0800"); // no `:` in the zone offset

------> java.time.format.DateTimeParseException: Text '2013-03-13T20:59:31-0800' could not be parsed, unparsed text found at index 22

I was able to solve this problem using the updated parser below:

var date = OffsetDateTime.parse("2013-03-13T20:59:31-0800", DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssZ"));

But this is not helping as this parser is now not converting the first date i.e. 2013-03-13T20:59:31-08:00 (with :) and throwing the exception

-----> java.time.format.DateTimeParseException: Text '2013-03-13T20:59:31-08:00' could not be parsed at index 19

As per my understanding from Wikipedia, both the dates seem to be in ISO 8601 format and should be converted via a single parser. Unfortunately, I could not find any common function and would like to understand how to tackle this situation?

I really don't want to manipulate the date string (maybe using regex etc) before passing it to the parser.

ihaider
  • 1,290
  • 4
  • 19
  • 38
  • 1
    It’s in the bottom part of [my answer here](https://stackoverflow.com/a/52017783/5772882). – Ole V.V. May 10 '22 at 08:56
  • 1
    @OleV.V. That was helpful. However, the pattern in your answer is not working for this date -> `2028-03-19T07:37:28+05:15:17`. Therefore, I played around with your solution, together with the solution by @rzwitserloot below, and came up with this pattern -> `uuuu-MM-dd'T'HH:mm:ss[XXXX][XXXXX][X]`. This is working for all the dates I could think of. Would appreciate your input on this. – ihaider May 10 '22 at 10:47
  • 1
    Thanks for reporting back. That is correct. According to [the documentation](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/format/DateTimeFormatter.html) you need five letters `X` or `x` for `+05:15:17`, which in turn also accepts the variant without seconds in the GMT offset, `+05:15`. (I doubt that any time zone is foreseen to use offset +05:15:17 in year 2028; but historic offsets with seconds precision exist in plenty numbers.) – Ole V.V. May 10 '22 at 11:17

1 Answers1

3

[] is how you introduce optional stuff.

I had to toy around with stuff for quite a while to make this work, but, you can:

var pattern = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss[XXXX][XXXXX]");
var date = OffsetDateTime.parse("2013-03-13T20:59:31-0830", pattern));
System.out.println(date);
var date2 = OffsetDateTime.parse("2013-03-13T20:59:31-08:30", pattern));
System.out.println(date2);

XXXX is the pattern for -0800, XXXXX is for -08:00.

By making them both optional, the 'right one' will be used.

EDIT: I had a completely different answer at first, that didn't actually work.

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
  • Good answer. A minor detail, it also works with `[XXX][XX]` since `XXX` matches the form with colon and `XX` the one without. – Ole V.V. May 10 '22 at 09:00
  • 1
    Thanks. However, this doesn't work for the following date: `2022-05-10T22:24:51+08`. I changed your pattern a little bit `uuuu-MM-dd'T'HH:mm:ss[XXXX][XXXXX][X]`. Now, all the dates are being parsed successfully (at least the ones I could think of) – ihaider May 10 '22 at 10:50
  • 1
    This updated pattern now works for the following dates: `2022-05-10T22:24:51Z`, `2022-05-10T22:24:51+08:55:17`, `2022-05-10T22:24:51+08`, `2022-05-10T22:24:51+08:00`, `2022-05-10T22:24:51-0800`, `2022-05-10T22:24:51+00:00`, `2022-05-10T22:24:51+0000` – ihaider May 10 '22 at 10:53
  • 1
    @ihaider It even works for 6 digit offset without colon too, for example `1890-03-13T20:59:31+035332` (the mentioned offset was used in Turmenistan back then according to [timeanddate.com](https://www.timeanddate.com/time/zone/turkmenistan/ashgabat)). – Ole V.V. May 10 '22 at 11:53