博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Jackson日期反序列化时区问题
阅读量:3962 次
发布时间:2019-05-24

本文共 2548 字,大约阅读时间需要 8 分钟。

文章转载自:、

一、问题描述

项目中有一个类,有记录销售日期的参数,为Date类型,我们传递的格式是"yyyy-MM-dd"

public class Product {
private Date saleDate; public Date getSaleDate() {
return saleDate; } public void setSaleDate(Date saleDate) {
this.saleDate = saleDate; }}

当我们用JSON格式将日期数据按照前端的日历控件传递到后端的时候,json字符串中日期格式没有问题,但是当反序列化为对象的时候,日期却加了"8:00:00"。

二、问题原因

让我们进入Jackson里 JsonFormat的源码看看:

/**     * Value that indicates that default {@link java.util.TimeZone}     * (from deserialization or serialization context) should be used:     * annotation does not define value to use.     *

* NOTE: default here does NOT mean JVM defaults but Jackson databindings * default, usually UTC, but may be changed on ObjectMapper. */ public final static String DEFAULT_TIMEZONE = "##default";

在JackSon中,会默认将时区设置为UTC时区,而Jackson反序列化时间类型的底层实际上调用的是Java的SimpleDateFormat#parse() 方法,而JAVA的jvm虚拟机则会根据你的操作系统来获取,所以JAVA认为你的时区应该是 GMT+8 时区,因此,反序列化的时候,需要将UTC --> GMT+8,就会将你传进来的时间+8个小时。

三、解决方案

  1. 在你每个日期类型的字段上的 @JsonFormat 加上属性 timezone="GMT+8"
@JsonFormat(pattern = "yyyy-MM-dd",timezone="GMT+8")private Date saleDate;
  1. 在Jackson中设置
ObjectMapper mapper = new ObjectMapper();mapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));

四、GMT和UTC

4.1 GMT-格林威治平时

GMT 的全名是格林威治标准时间或格林威治平时 (Greenwich Mean Time),这个时间系统的概念在 1884 年确立,由英国伦敦的格林威治皇家天文台计算并维护,并在往后的几十年往欧陆其他国家扩散。在 1924 年开始,格林威治天文台每小时就会向全世界播报时间。

在刚开始的几十年,GMT 的测量方法非常简单:观测者随时监控太阳在天空的位置,并且把每天太阳爬升到仰角最高的时候记录下来,这个时间点称呼为“过中天”。一般人对于一天 24 小时的理解,大致上就相等于两次太阳过中天的时间间隔。不过由于地球是以椭圆轨道绕着太阳,在轨道上的行进速率不一,导致一年之中会有“比较长的一天”与“比较短的一天”,所以格林威治的观测者必须要至少连续观测一年,然后求取 365 个长度不一的“天”,再把他们全部平均后,得到固定的一天长度,之后再细分成时、分、秒等单位。这个就是 GMT。

GMT 12:00 就是指的是英国伦敦郊区的皇家格林尼治天文台当地的中午12:00,而GMT+8 12:00,则是指的东八区的北京当地时间的12:00。

UTC-协调世界时

自从 1967 年国际度量衡大会把秒的定义改成铯原子进行固定震荡次数的时间后,时间的测量就可以与星球的自转脱节了。只利用原子钟计算时间与日期的系统,称作国际原子时 (International Atomic Time),这是一种只有“天”的系统,时分秒都以“天”的小数点零头来表示。以国际原子时为计算基准,把时间格式与 UT1 对齐,让一般人都方便使用的时间系统,就叫做协调世界时 (Universal Time Coordinated),也就是 UTC。这也就是 UTC 为什么与 GMT 几乎一样的关係。由于 UTC 直接与国际度量衡标准相联繫,所以目前所有的国际通讯系统,像是卫星、航空、GPS 等等,全部都协议採用 UTC 时间。

协调世界时,又称世界统一时间、世界标准时间、国际协调时间。协调世界时,即以我为基准,向我看齐的意思。(英语:Coordinated Universal Time,法语:Temps Universel Coordonné,简称UTC)是最主要的世界时间标准,由于英文(CUT)和法文(TUC)的缩写不同,作为妥协,简称UTC。

举例示范

比如在东京打工的你收到一封邮件:一位日本朋友在纽约给您寄了一封春节贺卡,请在2019年2月1日22:00之前到北京XX邮局取件。收到邮件后,我们第一反应是这个时间是什么地区的时间,纽约、东京、北京?看着自己的CASIO手表,你一脸懵逼无从决断。如果不确定这个时间类型GMT、UTC及时区的话,那么我们是没有办法明确知道此处所指的是何地的时间,当然也就没有办法转换成本地时间,从而工作和生活就会收到影响。

如果上述时间指的是纽约时间,那么纽约是GMT-5,所在地北京GMT+8,相差13个小时,转换成北京时间为2019年2月1号09:00。

如果上述时间指的是东京时间,那么东京是GMT+9,所在地北京GMT+8,相差1个小时,转换成北京时间为2019年2月1号21:00。

UTC + 时区差 = 本地时间

你可能感兴趣的文章
17-python之for循环
查看>>
18-python之while循环,for循环与else的配合
查看>>
19-python之字符串简单介绍
查看>>
20-python之切片详细介绍
查看>>
P24-c++类继承-01详细的例子演示继承的好处
查看>>
P8-c++对象和类-01默认构造函数详解
查看>>
P1-c++函数详解-01函数的默认参数
查看>>
P3-c++函数详解-03函数模板详细介绍
查看>>
P4-c++函数详解-04函数重载,函数模板和函数模板重载,编译器选择使用哪个函数版本?
查看>>
P5-c++内存模型和名称空间-01头文件相关
查看>>
P6-c++内存模型和名称空间-02存储连续性、作用域和链接性
查看>>
P9-c++对象和类-02构造函数和析构函数总结
查看>>
P10-c++对象和类-03this指针详细介绍,详细的例子演示
查看>>
Mule ESB-Content-Based Routing Tutorial(1)
查看>>
Mule ESB-Content-Based Routing Tutorial(2)
查看>>
Mule ESB-Content-Based Routing Tutorial(3)
查看>>
年末项目经验总结
查看>>
做事情要放下面子,拿起责任
查看>>
敏捷开发实践(1)-故事工作量估算导致的问题
查看>>
记一次解决jenkins持续构建,自动部署的问题
查看>>