1
votes

Quick (I suppose) question. How to parse string like that "2018-07-22 +3:00" to OffsetDateTime (setting time to 0:0:0.0)?

DateTimeFormatter formatter =cDateTimeFormatter.ofPattern("yyyy-MM-dd xxx");
OffsetDateTime dt = OffsetDateTime.parse("2007-07-21 +00:00", formatter);

java.time.format.DateTimeParseException: Text '2007-07-21 +00:00' could not be parsed: Unable to obtain OffsetDateTime from TemporalAccessor: {OffsetSeconds=0},ISO resolved to 2007-07-21 of type java.time.format.Parsed

2
Well, I did, of course. Ok, will add, but it's not workingBbIKTOP
@Andreas I added what I did, and how could it help?BbIKTOP
Your question text shows +3:00, which is an invalid offset since hour is only 1 digit, but your code shows +00:00 with 2-digit hour. Do you need to parse 1-digit hour or not?Andreas
@BbIKTOP Here. Here. And here.Basil Bourque

2 Answers

3
votes

An OffsetDateTime requires a time-of-day, but your format string doesn't supply that, so you need to tell the DateTimeFormatter to default time-of-day to midnight.

Also, offset +3:00 is invalid, since hour must be 2-digit, which means you need to fix that first.

This will do both:

public static OffsetDateTime parse(String text) {
    // Fix 1-digit offset hour
    String s = text.replaceFirst("( [+-])(\\d:\\d\\d)$", "$10$2");

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .appendPattern("uuuu-MM-dd xxx")
            .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
            .toFormatter();
    return OffsetDateTime.parse(s, formatter);
}

Test

System.out.println(parse("2018-07-22 +3:00"));
System.out.println(parse("2018-07-22 +03:00"));
System.out.println(parse("2007-07-21 +00:00"));

Output

2018-07-22T00:00+03:00
2018-07-22T00:00+03:00
2007-07-21T00:00Z
3
votes

The trick here is to start by getting the TemporalAccessor:

TemporalAccessor ta = DateTimeFormatter.ofPattern("yyyy-MM-dd XXX").parse("2018-07-22 +03:00");

From there, you can extract a LocalDate and a ZoneOffset:

LocalDate date = LocalDate.from(ta);
ZoneOffset tz = ZoneOffset.from(ta);

And combine them like so:

ZonedDateTime zdt = date.atStartOfDay(tz);