Javascript 和 Java 日期 JSON 序列化

Posted

技术标签:

【中文标题】Javascript 和 Java 日期 JSON 序列化【英文标题】:Javascript and Java Date JSON serialization 【发布时间】:2012-02-13 05:28:10 【问题描述】:

我有一个带有 Date 属性的 javascript 对象,它正在使用 JSON.stringify

转换为 JSON

我在 GMT+4 时区(俄罗斯/莫斯科)

例如, 5 Jan 2012 转换为 2012-01-04T20:00:00.000Z

5 Jan 1975 转换为 1975-01-04T20:00:00.000Z

但在 1975 年是 GMT+3 时区,因为 2011 年俄罗斯取消了夏令时。所以当涉及到服务器 (java) 时,它反序列化为:

2012-01-04T20:00:00.000Z 变成 5 Jan 2012 00:00 - 好的

1975-01-04T20:00:00.000Z 变为 4 Jan 1975 23:00 - 错误!

在 Javascript 中将 Date 对象转换为 JSON 的推荐方法是什么?

【问题讨论】:

这可能很有用。甚至可能重复:***.com/questions/4032967/json-date-to-java-date 【参考方案1】:

如果您使用 Spring Framework,您可以使用 @JsonSerialize@JsonDeserialize 注释。它将正确解析您的 javascript Date

例子:

public class product 

    @NotNull
    private Long id;
    
    @NotNull
    private String name;

    @JsonSerialize(using = CustomLocalDateSerializer.class)
    @JsonDeserialize(using = ISO8601LocalDateDeserializer.class)
    private LocalDate date;

    // getter and setter...

【讨论】:

【参考方案2】:

这个帖子比较老了。如今,使用 java 8,您应该在表单 dto 中使用 ZonedDateTime。使用 spring-mvc,Jackson 将正确地将 ISO 格式(例如:"2019-03-27T22:05:42.763Z")映射到 ZonedDateTime。

但是 Date.toISOString 方法始终将时区设置为 UTC,因此您的反序列化 ZonedDateTime 区域将始终设置为 UTC。如果您需要服务器端的区域,这可能是一个问题。例如,假设您需要向客户发送一封电子邮件,其中包含他/她刚刚通过表单提交的日期:您想使用相同的区域。

如果你想传递时区并遵守 ISO 格式,你应该使用像 moment.js 这样的库来格式化 javascript 中的日期。然后在序列化时:

moment().format('YYYY:MM:DDTHH:mm:ssZ') // "2019:03:27T23:06:11+01:00"

【讨论】:

【参考方案3】:

我更喜欢坚持使用 javascripts ISO 8601 日期格式, 正确解析时,它将自动处理时区差异。

在java中你可以解析一个javascript字符串化的JSON日期如下:

String iso8601Date = "2013-08-13T14:15:00.000Z";
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
Date parsedDate = formatter.parse(iso8601Date);

当把它转回字符串时,你会有这样的东西

//"2013-08-13T16:15:00.000+02:00"
String formattedDate = formatter.format(parsedDate);

为了解析 JSON,我使用 FlexJson,你可以像这样配置它。

//Serializing to JSON
DateTransformer dateTransformer = new DateTransformer("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
new JSONSerializer().transform(dateTransformer, Date.class).serialize(object);
//deserialize From JSON (replace object by java class)
JSONDeserializer<..Object..>().use(Date.class, dateTransformer).deserialize(json);

【讨论】:

我又是你的主意,因为传输像 'yyyy-MM-dd'T'HH:mm:ss.SSSXXX' 这样的长字符串不像数字时代那样有效。【参考方案4】:

我建议使用自纪元符号以来的秒数传递日期/时间,更具体地说,自 Unix 纪元(1970 年 1 月 1 日 00:00 GMT)以来的秒数。如果您对此不熟悉,这里有一个示例转换器:http://www.epochconverter.com/

这有几个优点:

它指的是独立于时区的同一时刻。这有助于独立于时区错误来存储时间(当然,它们必须首先正确输入)。 它是java.util.Date 中唯一不被弃用的构造函数(除了没有参数的构造函数),参见(getTime() 也是)。 (请注意,这使用毫秒。) JavaScript 可以很容易地从中构建日期(例如new Date(1000 * 1326894706))。 (请注意,这使用毫秒。) 如果重要的话,它总是会比"yyyy-MM-dd HH:mm:ss" 中的任何一个都小一点(就其 JSON 序列化中的数据大小而言)。 如果您希望时区被呈现并与此数字相关联,您总是可以在您的表示中添加一个额外的字段。 "datetime": 1326894706, "tz": "GMT" 仍然比 "datetime": "18 Jan 2012 13:51:46 GMT" 短。

考虑到在 Java 和 JavaScript 中很容易从中获取 Date 实例,您可以使用 DateFormatter 将其与 Java 中的文本进行转换。对于 JavaScript,使用诸如 Date Format 之类的库将帮助您在页面上适当地呈现它(例如使用诸如 new Date(val * 1000).format("yyyy-mm-dd HH:MM") 之类的东西)。

【讨论】:

我做了更多的研究,发现 epoch 在 java 和 javascript (***.com/questions/8913059/…) 中的处理方式不同。如果我不能依赖 getTime() 方法,我不知道如何使用纪元时间。 它们只是在将时区与您当时的位置联系起来的方式上有所不同。我以为您的输入首先是(正确的)JS Date 实例?你如何建造它们?你能举一个例子说明你最初是如何产生5 Jan 1975的吗? 当在日历中选择 1975 年 1 月 5 日时,我从 jQuery DatePicker $("date").datePicker("getTime") 获取日期。然后使用 JSON.stringify 将其序列化为 JSON,它使用与年份无关的 4 小时差异。但是 Java 知道在 2011 年之前它是 GMT+3 并以正确的方式反序列化它,所以我在 2011 年之前的日期有 1 小时的差异 另一个优点是比较容易 - 您不需要反序列化来比较日期。【参考方案5】:

JSON 不支持日期,所有解析器/序列化器都使用 toString 或类似的东西。序列化/反序列化日期由您决定。 由于 Javascript 没有包含像样的日期格式化程序,最简单的解决方案是将日期转换为长。但是,如果您希望能够阅读正在发生的事情,我建议 http://www.datejs.com/ 并将日期格式化为 yyyy-MM-dd HH:mm:ss

【讨论】:

【参考方案6】:

我个人会使用类似这样的方法将它们转换为 java 中的字符串:

String theDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);

然后字符串被序列化。在你的javascript方面,只需解析它。

【讨论】:

我认为问题出在 from JavaScript to Java。 或者相反:在 Javascript 中字符串化以在 Java 中解析,因为作者想要 Javascript-> Java,如果我正确阅读了问题。 是的,我正在考虑为 Spring MVC+Jackson 编写自定义日期序列化器/反序列化器。

以上是关于Javascript 和 Java 日期 JSON 序列化的主要内容,如果未能解决你的问题,请参考以下文章

Jackson JSON对日期格式的解析设置

将 Json 日期字符串转换为 JavaScript 日期对象

JavaScript--标准对象(Data日期对象 & Json对象)

与 javascript 日期相比,Json Stringify 日期产生错误的日​​期

JavaScript json日期格式正则表达式

无法从 JavaScript 中的 JSON 文件获取具有日期格式的对象 [重复]