How to parse ZonedDateTime with default zone?

后端 未结 2 1267
野的像风
野的像风 2020-12-09 17:52

How to parse ZoneDateTime from string that doesn\'t contain zone and others fields?

Here is test in Spock to reproduce:

imp         


        
2条回答
  •  生来不讨喜
    2020-12-09 18:36

    Since the ISO_ZONED_DATE_TIME formatter expects zone or offset information, parsing fails. You'll have to make a DateTimeFormatter that has optional parts for both the zone information and the time part. It's not too hard reverse engineering the ZonedDateTimeFormatter and adding optional tags.

    Then you parse the String using the parseBest() method of the formatter. Then, for suboptimal parse results you can create the ZonedDateTime using any default you want.

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .parseCaseInsensitive()
            .append(ISO_LOCAL_DATE)
            .optionalStart()           // time made optional
            .appendLiteral('T')
            .append(ISO_LOCAL_TIME)
            .optionalStart()           // zone and offset made optional
            .appendOffsetId()
            .optionalStart()
            .appendLiteral('[')
            .parseCaseSensitive()
            .appendZoneRegionId()
            .appendLiteral(']')
            .optionalEnd()
            .optionalEnd()
            .optionalEnd()
            .toFormatter();
    
    TemporalAccessor temporalAccessor = formatter.parseBest(value, ZonedDateTime::from, LocalDateTime::from, LocalDate::from);
    if (temporalAccessor instanceof ZonedDateTime) {
        return ((ZonedDateTime) temporalAccessor);
    }
    if (temporalAccessor instanceof LocalDateTime) {
        return ((LocalDateTime) temporalAccessor).atZone(ZoneId.systemDefault());
    }
    return ((LocalDate) temporalAccessor).atStartOfDay(ZoneId.systemDefault());
    

提交回复
热议问题