java 无法从 TemporalAccessor 获取 OffsetDateTime

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35298214/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 23:58:22  来源:igfitidea点击:

Unable to obtain OffsetDateTime from TemporalAccessor

javajava-8java-time

提问by asmaier

When I do this

当我这样做时

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

I get the following exception:

我收到以下异常:

    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

How can I parse my datetime string so that it is interpreted as always being from the timezone "Europe/Berlin" ?

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

回答by Tunaki

The problem is that there is a difference between what a ZoneIdis and a ZoneOffsetis. To create a OffsetDateTime, you need an zone offset. But there is no one-to-one mapping between a ZoneIdand a ZoneOffsetbecause it actually depends on the current daylight saving time. For the same ZoneIdlike "Europe/Berlin", there is one offset for summer and a different offset for winter.

问题是 a ZoneIdis 和 a ZoneOffsetis之间存在差异。要创建OffsetDateTime,您需要一个区域偏移量。但是aZoneId和 a之间没有一一对应的关系,ZoneOffset因为它实际上取决于当前的夏令时。对于与ZoneId“欧洲/柏林”一样的情况,夏季有一个偏移量,冬季有不同的偏移量。

For this case, it would be easier to use a ZonedDateTimeinstead of an OffsetDateTime. During parsing, the ZonedDateTimewill correctly be set to the "Europe/Berlin"zone id and the offset will also be set according to the daylight saving time in effect for the date to parse:

对于这种情况,使用 aZonedDateTime而不是会更容易OffsetDateTime。在解析过程中,ZonedDateTime将正确设置为"Europe/Berlin"区域 id,偏移量也将根据解析日期生效的夏令时设置:

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)
}

Note that if you really want an OffsetDateTime, you can use ZonedDateTime.toOffsetDateTime()to convert a ZonedDateTimeinto an OffsetDateTime.

请注意,如果您真的想要OffsetDateTime,则可以使用ZonedDateTime.toOffsetDateTime()将 aZonedDateTime转换为OffsetDateTime

回答by Matt Johnson-Pint

There's no offset in your source data, and thus OffsetDateTimeis not the correct type to use during parsing.

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

Instead, use a LocalDateTime, since that is the type that most closely resembles the data you have. Then use atZoneto assign it a time zone, and if you still need an OffsetDateTime, you can call toOffsetDateTimefrom there.

相反,请使用 a LocalDateTime,因为这是与您拥有的数据最相似的类型。然后使用atZone给它分配一个时区,如果你仍然需要一个OffsetDateTime,你可以toOffsetDateTime从那里调用。

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();