2

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.

  • Avoid parsing time zone abbreviations like `AEST` if you can. While `AEST` may be unambiguous, most of the most common abbreviations are ambiguous, and you don’t know what you get. – Ole V.V. Oct 25 '21 at 11:51

2 Answers2

3

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.

MC Emperor
  • 22,334
  • 15
  • 80
  • 130
  • Thank you so much for your answer. If I can ask you for suggestions, how do you recommend someone to improve their java skills? – Sajjan Mishra Oct 18 '21 at 07:38
  • 1
    I passed `Locale.ROOT` to `toFormatter` because `DateTimeFormatter` is locale-sensitive, and for my default locale "Oct" didn't work. – MC Emperor Oct 18 '21 at 07:40
  • 2
    Well, regarding improving Java skills — by experimenting, but also reading up on the matter. And make sure that you grab tutorials or books which are not outdated. – MC Emperor Oct 18 '21 at 07:43
1

You can try using try-catch block

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

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

ZonedDateTime zonedDateTime;
try {
    zonedDateTime = ZonedDateTime.parse(dateTime, dtf1);
} catch (DateTimeParseException e) {
    zonedDateTime = ZonedDateTime.parse(dateTime, dtf2);
}
Instant instant = zonedDateTime.toInstant();
Date finalDate = Date.from(instant);
Akshay Batra
  • 137
  • 7
  • Thank you so much for your answer and help. I feel the answer given by MC Emperor is more concise so marking his answer as right one – Sajjan Mishra Oct 18 '21 at 07:31