Search code examples
javadatetimejava-8zoneddatetimedatetimeformatter

DateTimeFormatter to parse string with both Zone offset and timezone


This question might sound similar to most of the other questions asked here on Stackoverflow but I could not figure out my problem. I want to parse the string value into a date.

String dateTime = "23 Oct 2020 02:44:58 +1000"

The solution to this problem is:

DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
builder.parseCaseInsensitive();
builder.appendPattern("d MMM yyyy HH:mm[:ss] Z");
DateTimeFormatter dtf = builder.toFormatter();

ZonedDateTime zonedDateTime = ZonedDateTime.parse(dateTime, dtf);
Instant instant = zonedDateTime.toInstant();
Date finalDate = Date.from(instant);

If I want to parse the date with timezone instead like String dateTime = "23 Oct 2020 02:44:58 AEST" then I need to change the builder.appendPattern("d MMM yyyy HH:mm[:ss] Z"); from capital Z to small z as mentioned here.

The question here is how would I make my parser flexible enough for it to handle either timezone or offset value?

Note. I have used [ss] as the seconds' field is optional. And as per documentation using VV was similar to z while 'V' did not work for me.


Solution

  • You can add them as optional parts to the formatter, just like you did with the seconds part:

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
        .parseCaseInsensitive()
        .appendPattern("d MMM yyyy HH:mm[:ss] [Z][z]")
        .toFormatter(Locale.ROOT);
    

    Online demo

    [ and ] denote an optional part: the corresponding text is consumed if it can be successfully parsed by means of the pattern within the brackets, otherwise, no text is consumed and the pattern within is skipped.