java.time.OffsetDateTime:无法从 TemporalAccessor 获取 OffsetDateTime

问题描述 投票:0回答:3

我正在尝试使用

"20140726080320+0400"
格式解析
"yyyyMMddHHmmssZ"
,如下所示:

System.out.println("********************" + OffsetDateTime
    .parse("20140726080320+0400",
        DateTimeFormatter.ofPattern("yyyyMMddHHmmssZ").withChronology(IsoChronology.INSTANCE).withResolverStyle(STRICT))
    .toEpochSecond()); 

我一直遇到这个异常:

java.time.format.DateTimeParseException: Text '20140726080320+0400' could not be parsed: Unable to obtain OffsetDateTime from TemporalAccessor: {OffsetSeconds=14400, DayOfMonth=26, YearOfEra=2014, MonthOfYear=7},ISO resolved to 08:03:20 of type java.time.format.Parsed
    at java.time.format.Parsed.getLong(Parsed.java:203)
    at java.time.Instant.from(Instant.java:373)
    at java.time.OffsetDateTime.from(OffsetDateTime.java:365)
    at java.time.format.Parsed.query(Parsed.java:226)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
    at java.time.OffsetDateTime.parse(OffsetDateTime.java:402)

我做错了什么?

java java-time timezone-offset datetime-parsing java.time.instant
3个回答
2
投票
格式模式字符串中的

yyyy
代表纪元年份。严格来说,2014 年可以表示 2014 BCE(“基督之前”)或 2014 CE(“anno Domini”)。显然,具有严格解析器风格的格式化程序反对这种歧义。

解决方案是使用

uuuu
表示年份。这是一个有符号的年份,其中 0 表示公元前 1 年,-1 表示公元前 2 年,依此类推。所以没有歧义:

    System.out.println("********************"
            + OffsetDateTime.parse("20140726080320+0400",
                                DateTimeFormatter.ofPattern("uuuuMMddHHmmssZ")
                                        .withChronology(IsoChronology.INSTANCE)
                                        .withResolverStyle(STRICT))
                        .toEpochSecond());

此打印

********************1406347400

这与

IsoChronology
解析不同解析器样式的日期的方式有关,如javadoc中所述:

如果仅存在 YEAR_OF_ERA,并且模式为智能或宽松,则假定当前时代(CE/AD)。在严格模式下,不假定任何时代,并且 YEAR_OF_ERA 保持不变。


0
投票

试试这个:

LocalDateTime.parse("20140726080320+0400",
    new DateTimeFormatterBuilder().appendPattern("yyyyMMddHHmmssZ").toFormatter())
.atOffset(ZoneOffset.UTC)

返回:

2014-07-26T08:03:20


这是错误的,因为它忽略了偏移量 (+0400),然后将日期/时间设置为 UTC - 这将为 epochSecond 提供错误的值


0
投票

也许我的答案已经过时了,但我刚刚处理过类似的问题 -)

如果您想使用严格模式,并继续使用“yyyy”而不是“uuuu”,那么您需要添加ERA的指示。我使用默认值,如下所示:

    OffsetDateTime.parse("20140726080320+0400", 
     new DateTimeFormatterBuilder()
         .appendPattern("yyyyMMddHHmmssZ")
         .parseDefaulting(ChronoField.ERA, 1)
         .toFormatter()
         .withResolverStyle(ResolverStyle.STRICT)
);

此代码工作正常。 我希望这对某人有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.