无法从 TemporalAccessor 获取 OffsetDateTime

2022-09-01 17:21:25

当我这样做时

String datum = "20130419233512";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(ZoneId.of("Europe/Berlin"));
OffsetDateTime datetime = OffsetDateTime.parse(datum, formatter);

我得到以下异常:

    java.time.format.DateTimeParseException: Text '20130419233512' could not be parsed: 
Unable to obtain OffsetDateTime from TemporalAccessor: {InstantSeconds=1366407312},ISO,Europe/Berlin resolved 
to 2013-04-19T23:35:12 of type java.time.format.Parsed

如何解析我的日期时间字符串,以便将其解释为始终来自时区“欧洲/柏林”?


答案 1

问题是a是什么和a是有区别的。要创建 ,您需要一个区域偏移。但是,ZoneIdZoneOffset 之间没有一对一的映射,因为它实际上取决于当前的夏令时。对于像“欧洲/柏林”这样的相同内容,夏季有一个偏移量,冬季有一个不同的偏移量。ZoneIdZoneOffsetOffsetDateTimeZoneId

对于这种情况,使用 而不是 .在解析过程中,将正确设置为区域 ID,并且还将根据要分析的日期的有效夏令时设置偏移量:ZonedDateTimeOffsetDateTimeZonedDateTime"Europe/Berlin"

public static void main(String[] args) {
    String datum = "20130419233512";
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(ZoneId.of("Europe/Berlin"));
    ZonedDateTime datetime = ZonedDateTime.parse(datum, formatter);

    System.out.println(datetime.getZone()); // prints "Europe/Berlin"
    System.out.println(datetime.getOffset()); // prints "+02:00" (for this time of year)
}

请注意,如果您确实想要 一个 ,则可以使用 ZonedDateTime.toOffsetDateTime() 将 a 转换为 .OffsetDateTimeZonedDateTimeOffsetDateTime


答案 2

源数据中没有偏移量,因此在分析过程中使用的类型不正确。OffsetDateTime

请改用 ,因为这是与您拥有的数据最相似的类型。然后用于为其分配一个时区,如果仍然需要一个,则可以从那里拨打电话。LocalDateTimeatZoneOffsetDateTimetoOffsetDateTime

String datum = "20130419233512";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
LocalDateTime datetime = LocalDateTime.parse(datum, formatter);
ZonedDateTime zoned = datetime.atZone(ZoneId.of("Europe/Berlin"));
OffsetDateTime result = zoned.toOffsetDateTime();

推荐