Jackson 将 ISO8601 格式的日期时间反序列化为 Java8 Instant

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36252556/
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-08-11 17:37:33  来源:igfitidea点击:

Hymanson deserialize ISO8601 formatted date-time into Java8 Instant

javajsondatetimeHymansonjava-8

提问by Kre?imir Nesek

I'm trying to deserialize an ISO8601 formatted date into Java8 Instant using Hymanson. I registered JavaTimeModule with the ObjectMapper, turned off WRITE_DATES_AS_TIMESTAMPS.

我正在尝试使用 Hymanson 将 ISO8601 格式的日期反序列化为 Java8 Instant。我用 ObjectMapper 注册了 JavaTimeModule,关闭了 WRITE_DATES_AS_TIMESTAMPS。

However, if one tries to deserialize 2016-03-28T19:00:00.000+01:00 it will not work, because it seems that JavaTimeModule will only deserialize date-times formatted with UTC timezone offset (e.g. 2016-03-28T18:00:00.000Z). I then tried using @JsonFormat annotation like this:

但是,如果尝试反序列化 2016-03-28T19:00:00.000+01:00 它将不起作用,因为 JavaTimeModule 似乎只会反序列化使用 UTC 时区偏移量格式的日期时间(例如 2016-03-28T18:00 :00.000Z)。然后我尝试使用这样的 @JsonFormat 注释:

@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = "UTC")

And like this:

像这样:

@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = JsonFormat.DEFAULT_TIMEZONE)

However, neither of these work and I get an exception:

但是,这些都不起作用,我得到了一个例外:

com.fasterxml.Hymanson.databind.JsonMappingException: Unsupported field: YearOfEra (through reference chain: org.example.Article["date"])

Which implies that timezone parameter is ignored and date time formatter doesn't know how to format an Instant without a timezone.

这意味着时区参数被忽略,日期时间格式化程序不知道如何在没有时区的情况下格式化 Instant。

Is there a way to deserialize a ISO8601 string that's not in UTC time zone offset to Java 8 Instant using Hymanson and JavaTimeModule without writing custom deserializer?

有没有办法使用 Hymanson 和 JavaTimeModule 将不在 UTC 时区偏移量中的 ISO8601 字符串反序列化到 Java 8 Instant 而无需编写自定义反序列化器?

采纳答案by Meiko Rachimow

You need to set the explicit time zone via XXXin your modell class:

您需要通过XXX在您的模型类中设置显式时区:

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")

(see: https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html)

(参见:https: //docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

回答by Mick Belker - Pseudonym

The format "Z" does not work with "+01:00" as this is a different pattern. JsonFormat is using SimpleDateFormat patterns. "Z" in upper caseonly represents strict RFC 822. You have to use syntax like: "+0100", without colon.

格式“Z”不适用于“+01:00”,因为这是一种不同的模式。JsonFormat 使用 SimpleDateFormat 模式。大写的“Z”仅代表严格的 RFC 822。您必须使用类似以下的语法:“+0100”,不带冒号。

See: ISO 8601:2004, SimpleDateFormat patterns

请参阅:ISO 8601:2004SimpleDateFormat 模式

回答by Guss

If you want to serialize Dateobjects into ISO-8601, you don't need to specify a pattern at all - ISO-8601 is the default pattern. It is kind of mentioned in the JsonFormatJava doc:

如果要将Date对象序列化为 ISO-8601,则根本不需要指定模式 - ISO-8601 是默认模式。它在JsonFormatJava 文档中有所提及:

Common uses include choosing between alternate representations -- for example, whether Date is to be serialized as number (Java timestamp) or String (such as ISO-8601 compatible time value)-- as well as configuring exact details with pattern() property.

常见用途包括在替代表示之间进行选择——例如,将日期序列化为数字(Java 时间戳)还是字符串(例如 ISO-8601 兼容的时间值)——以及使用 pattern() 属性配置确切的细节。

[emphasasis mine] you should understand from the above text that specifying shape = STRINGwould mean an ISO-8601 format but you can choose something else using the patternproperty.

[强调我的] 你应该从上面的文本中了解到指定shape = STRING意味着 ISO-8601 格式,但你可以使用该pattern属性选择其他内容。

In my experience, this always turns out a UTC date format (with the time zone rendered as +0000), which could be the default time zone in my VM (even though my operating system clock is not set to UTC).

根据我的经验,这总是会产生 UTC 日期格式(时区呈现为+0000),这可能是我的 VM 中的默认时区(即使我的操作系统时钟未设置为 UTC)。

回答by zoomout

In Hymanson 2.9.8 (current one as I'm writing this) it's better to use Instant instead of Date.

在 Hymanson 2.9.8(我写这篇文章时的当前版本)中,最好使用 Instant 而不是 Date。

You have to add a dependency:

您必须添加一个依赖项:

<dependency>
    <groupId>com.fasterxml.Hymanson.datatype</groupId>
    <artifactId>Hymanson-datatype-jsr310</artifactId>
    <version>2.9.8</version>
</dependency> 

Also, register the module and configure SerializationFeature.WRITE_DATES_AS_TIMESTAMPS to false.

此外,注册模块并将 SerializationFeature.WRITE_DATES_AS_TIMESTAMPS 配置为 false。

new ObjectMapper()
                .findAndRegisterModules()
                .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

More information about Hymanson for Java8 here: https://github.com/FasterXML/Hymanson-modules-java8

更多关于 Hymanson for Java8 的信息:https: //github.com/FasterXML/Hymanson-modules-java8