Generic DateTimeFormatter pattern for ISO 8601 datetime string with zone offset

1k views Asked by At

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.

1

There are 1 answers

4
rzwitserloot On

[] 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.