OffsetDateTime.parse的Threeten DateTimeParseException(String,dateTimeFormatter)

时间:2018-05-04 14:20:15

标签: java threetenbp

我想简单地在DateTimeFormatter解析器中使用OffsetDateTime。但我得到DateTimeParseException

final DateTimeFormatter ISO_LOCAL_DATE;
ISO_LOCAL_DATE = new DateTimeFormatterBuilder()
    .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
    .appendLiteral('-')
    .appendValue(MONTH_OF_YEAR, 2)
    .appendLiteral('-')
    .appendValue(DAY_OF_MONTH, 2)
    .appendLiteral('T')
    .appendValue(HOUR_OF_DAY,2)
    .appendLiteral(':')
    .appendValue(MINUTE_OF_HOUR,2)
    .appendLiteral(':')
    .appendValue(SECOND_OF_MINUTE,2)
    .toFormatter().withResolverStyle(ResolverStyle.STRICT).withChronology(IsoChronology.INSTANCE);

DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
OffsetDateTime.parse("2012-03-06T00:00:00",ISO_LOCAL_DATE);

我调查了一个类似的问题,但也没有任何线索:/ 上面的代码有什么问题? ......与Formatter还是Threeten lib?

1 个答案:

答案 0 :(得分:1)

您没有在输入数据中指定偏移量。

这是带偏移的日期时间示例:

2012-03-06T00:00+01:00

ZonedDateTime的示例:

2012-03-06T00:00+02:00[Europe/Paris]

Europe/Berlin - 可以在此处视为ZoneId。但是每个区域可能在一年中的不同时间(夏季/冬季时间)具有不同的偏移量。

ZoneIdZoneOffset之间没有一对一的映射关系: Is there any way to convert ZoneId to ZoneOffset in java 8?

您可以指定ZoneOffset而不是指定ZoneId,而是自动确定偏移量。

然后,您可以获取ZonedDateTime并将其转换为OffsetDateTime

public OffsetDateTime ZonedDateTime.toOffsetDateTime()
     

使用本地日期时间和偏移量创建偏移日期时间。   区域ID被忽略。

针对您的案例指定ZoneId

的修复程序
public class Main {
    private static final DateTimeFormatter ISO_LOCAL_DATE = new DateTimeFormatterBuilder()
            .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
            .appendLiteral('-')
            .appendValue(MONTH_OF_YEAR, 2)
            .appendLiteral('-')
            .appendValue(DAY_OF_MONTH, 2)
            .appendLiteral('T')
            .appendValue(HOUR_OF_DAY,2)
            .appendLiteral(':')
            .appendValue(MINUTE_OF_HOUR,2)
            .appendLiteral(':')
            .appendValue(SECOND_OF_MINUTE,2)
            .toFormatter()
            .withResolverStyle(ResolverStyle.STRICT)
            .withChronology(IsoChronology.INSTANCE)
            .withZone(ZoneId.systemDefault()); // or whatever you have

    public static void main(String[] args) {
        ZonedDateTime zonedDateTime = ZonedDateTime.parse("2012-03-06T00:00:00", ISO_LOCAL_DATE);
        System.out.println(zonedDateTime);
        System.out.println(zonedDateTime.toOffsetDateTime());
    }
}

近似输出:

2012-03-06T00:00+01:00[Europe/City]
2012-03-06T00:00+01:00

要修复的第二个选项 - 将offsetId()添加到解析器构建器并为输入字符串指定偏移部分:

public class Main {
    private static final DateTimeFormatter ISO_LOCAL_DATE = new DateTimeFormatterBuilder()
            .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
            .appendLiteral('-')
            .appendValue(MONTH_OF_YEAR, 2)
            .appendLiteral('-')
            .appendValue(DAY_OF_MONTH, 2)
            .appendLiteral('T')
            .appendValue(HOUR_OF_DAY,2)
            .appendLiteral(':')
            .appendValue(MINUTE_OF_HOUR,2)
            .appendLiteral(':')
            .appendValue(SECOND_OF_MINUTE,2)
            .appendOffsetId()
            .toFormatter()
            .withResolverStyle(ResolverStyle.STRICT)
            .withChronology(IsoChronology.INSTANCE);

    public static void main(String[] args) {
        OffsetDateTime offsetDateTime = OffsetDateTime.parse("2012-03-06T00:00:00+02:00", ISO_LOCAL_DATE);
        System.out.println(offsetDateTime);
    }
}

输出:

2012-03-06T00:00+02:00

您可以指定自己的偏移模式而不是.appendOffsetId(),如:

.appendOffset("+HH:mm", "Z")

顺便说一句,有很多标准的DateTimeFormatter可以用来解析OffsetDateTime

public class Main {
    public static void main(String[] args) {
        String offsetStringTime = "2012-03-06T00:00:00+02:00";
        OffsetDateTime offsetDateTime = OffsetDateTime.parse(offsetStringTime);
        OffsetDateTime offsetDateTime2 = OffsetDateTime.parse(offsetStringTime, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
        OffsetDateTime offsetDateTime3 = OffsetDateTime.parse(offsetStringTime, DateTimeFormatter.ISO_ZONED_DATE_TIME);
        System.out.println(offsetDateTime);
        System.out.println(offsetDateTime2);
        System.out.println(offsetDateTime3);
    }
}

输出:

2012-03-06T00:00+02:00
2012-03-06T00:00+02:00
2012-03-06T00:00+02:00