B_Osipiuk
B_Osipiuk

Reputation: 1048

ISO_DATE_TIME.format() to LocalDateTime with optional offset

I am trying to covert ISO date time to LocalDateTime:

String timezone = "Pacific/Apia";
String isoDateTime = "2011-12-03T10:15:30+03:00";
var zoned = ZonedDateTime.from(ISO_DATE_TIME_FORMATTER.parse(isoDateTime));
return zoned.withZoneSameInstant(ZoneId.of(timeZone)).toLocalDateTime();

This code works - it convert it to localdate including offset. But the problem is when I pass date without offset: 2011-12-03T10:15:30 -

java.time.DateTimeException: Unable to obtain ZonedDateTime from TemporalAccessor: {},ISO resolved to 2011-12-03T10:15:30 of type java.time.format.Parsed

I know why I have got this exception, the question is How to convert both dates including offsets to LocalDateTime?. I want to avoid some string parsing (check if the string contains '+'/'-').

Upvotes: 2

Views: 1900

Answers (2)

NorthernSky
NorthernSky

Reputation: 498

You can build a parser with an optional offset element, and use TemporalAccessor.isSupported to check if the offset was present.

    DateTimeFormatter parser = new DateTimeFormatterBuilder()
        .parseCaseInsensitive()
        .append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
        .optionalStart()
        .appendOffsetId()
        .optionalEnd()
        .toFormatter();

    TemporalAccessor accessor = parser.parse(isoDateTime);
    if (accessor.isSupported(ChronoField.OFFSET_SECONDS)) {
        var zoned = ZonedDateTime.from(accessor);
        return zoned.withZoneSameInstant(ZoneId.of(timezone)).toLocalDateTime();
    }
    return LocalDateTime.from(accessor);

Upvotes: 7

leonardkraemer
leonardkraemer

Reputation: 6813

You can handle the parse exception in a catch clause and try a different parser. For example like this:

String timezone = "Pacific/Apia"
String isoDateTime = "2011-12-03T10:15:30+03:00";    
try{
    var zoned = ZonedDateTime.from(ISO_DATE_TIME_FORMATTER.parse(isoDateTime));
    return zoned.withZoneSameInstant(ZoneId.of(timeZone)).toLocalDateTime();
} catch (DateTimeException e) {
    //no time zone information -> parse as LocalDate
    return LocalDateTime.parse(isoDateTime);
}

Upvotes: 0

Related Questions