首页 > 编程语言 >JAVA开发使用@JsonFormat注解,日期比实际日期少一天问题

JAVA开发使用@JsonFormat注解,日期比实际日期少一天问题

时间:2024-05-11 18:19:06浏览次数:30  
标签:JsonFormat JAVA pattern 日期 timezone 注解 GMT

前言

最近同事反馈一个问题,说是日期保存后未发生变化。刚开始以为是字段未对应或者是未保存成功,当我去进行排查的时候发现,发现数据保存没有问题。奇了怪了。

问题现象

库里日期数据保存正确,但是后台返回前台页面发现不正确。

排查过程

刚开始怀疑是数据未保存成功,经过测试发现数据正常保存进数据库中。

有转变方向根据Debug走了一遍数据查询过程,发现问题所在。

后台查询结果正确,但是经过controller层响应前台时,日期发生了变化。OK,问题定位,检查日期格式转换。

发现后台实体中日期转换使用@JsonFormat注解,但是转换格式没有发现问题

@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")

根据网上解决方案调整timezone 与 pattern 的顺序,未成功解决。

最后在一篇文章中找到答案并解决,特来记录这个有意思的小bug。

关于@JsonFormat注解

@JsonFormat注解,是在Jackson中定义的一个注解,是一个时间格式化注解。此注解用于属性上,作用是把DATE类型的数据转化成为我们想要的格式。

通俗点来说,是后台数据转换为指定日期格式返回给前台时使用的。

  • pattern(模式): 通过 pattern 属性,您可以指定日期和时间的格式。
    例如,如果要将日期格式设置为"yyyy-MM-dd",可以使用 @JsonFormat(pattern = "yyyy-MM-dd")
  • timezone(时区): 使用 timezone 属性可以指定日期和时间的时区。这对于确保正确地处理跨时区的日期数据很重要。
  • locale(区域设置): 通过 locale 属性,您可以指定用于格式化的区域设置,以便支持不同的语言和地区。
  • shape(形状): shape 属性定义了序列化后的日期表示形式。例如,您可以将日期表示为字符串或时间戳。
  • with(特定类型的格式): 使用 with 属性,您可以为不同的 Java 类型指定不同的格式。这对于处理不同类型的日期数据非常有用。

注意:我们在格式化的时候要指定时区(timezone ),是因为@JsonFormat注解默认的时区为格林尼治时间,比中国时间(东八区是要小8个小时的)。

中国的默认时区是东八区

时区概念

GMT:Greenwich Mean Time 格林尼治标准时间。这是以英国格林尼治天文台观测结果得出的时间,这是英国格林尼治当地时间,这个地方的当地时间过去被当成世界标准的时间。

UT:Universal Time 世界时。根据原子钟计算出来的时间。

UTC:Coordinated Universal Time 协调世界时。因为地球自转越来越慢,每年都会比前一年多出零点几秒,每隔几年协调世界时组织都会给世界时+1秒,让基于原子钟的世界时和基于天文学(人类感知)的格林尼治标准时间相差不至于太大。并将得到的时间称为UTC,这是现在使用的世界标准时间。

协调世界时不与任何地区位置相关,也不代表此刻某地的时间,所以在说明某地时间时要加上时区

也就是说GMT并不等于UTC,而是等于UTC+0,只是格林尼治刚好在0时区上。

GMT = UTC+0

格林尼治时间(GMT)、世界协调时间(UTC)和中国时间的关系

中国时间(Asia/Shanghai) = 格林尼治时间(GMT) + 8
格林尼治时间(GMT) = 世界协调时间(UTC) + 0

问题原因

中国在1986年至1991年实行过夏令时,即在这些年份北京时间比GMT提前9个小时。所以使用注解@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")看起来像是未起作用。

解决方案

使用下面的注解替换@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")

@JsonFormat(pattern = "yyyy-MM-dd", locale = "zh", timezone = "Asia/Shanghai")

参考文章

  1. 解决年份为1986~1991时,使用注解@JsonFormat(pattern = “yyyy-MM-dd“, timezone = “GMT+8“)仍然比实际日期少一天

2.格式化日期注解@JsonFormat的使用和TimeZone时区问题

标签:JsonFormat,JAVA,pattern,日期,timezone,注解,GMT
From: https://www.cnblogs.com/sansui6/p/18187001

相关文章

  • JAVA LIST按照指定字段去重重复
    JAVAList按照指定字段去重重复List<TalentPlanStudentEntity>studentList=relatePlanStudentList.stream() .collect(Collectors.collectingAndThen(Collectors.toCollection( ()->newTreeSet<>(Comparator.comparing(TalentPlanStudentEntity::getUserId......
  • Java-线程-并发问题和ConcurrentHashMap
    0.背景在经典八股文中,我们会背:啊,hashmap是线程不安全的,concurrentHashMap是线程安全的。然后呢,又背:啊,为啥ConcurrentHashMap是安全的,因为加锁了。好好好,接着八股:啊,啥啥分段锁。本文,结合实际例子来进行分析,这他妈的到底是在叭叭啥。一切,从一个Hashmap的demo谈起。pu......
  • JavaScript 生成32位UUID
    functionuuid(){varlen=32;//32长度varradix=16;//16进制varchars='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');varuuid=[],i;radix=radix||chars.length;if(......
  • JavaScript 原型链与继承问答(第一天)
    1、在编程语言中,什么叫语法糖在编程语言中,"语法糖"是指一种编程语言的语法功能,它并不改变语言的功能,但可以让代码更易读、更易写。它是一种语法上的简化,让程序员能够用更少的代码表达相同的逻辑。比如es6中,一个对象想复用另外一个对象的所有字段,可以这样constobj2={...obj......
  • 【Java】创建对象的几种方式
    1.new创建新的对象Stringstr=newString("str");2.通过Java的反射机制publicstaticvoidmain(String[]args)throwsException{//获取类的Class对象Stringstr=(String)Class.forName("java.lang.String").newInstance();System.out......
  • 【Java】的四种引用类型
    (一)强引用Java强引用最常见,就是把一个对象赋给一个引用变量,这个引用变量就是强引用,但一个对象被强引用时,它处于可达状态,不会被垃圾回收装置回收,因此强引用是造成内存泄漏的主要原因之一。Strings=newString("ABC");(2)软引用软引用需要SoftReference类来实现,对于只有软引......
  • Java开发利器Commons Lang之元组Tuple
    标准Java库没有提供足够的方法来操作其核心类,ApacheCommonsLang提供了这些额外的方法。ApacheCommonsLang为java提供了大量的帮助工具。langAPI,特别是String操作方法、基本数值方法、对象反射、并发、创建和序列化以及System属性。此外,它还包含对java.util.Date的基本增......
  • [附源码+文档]Java Swing小游戏源码合集(14款)_毕业设计必选项目
    (小众游戏塔防迷宫动作剧情类等)16款游戏源码Javaswing五子棋联网版源代码Javaswing贪吃蛇游戏开发教程+源码Javaswing超级玛丽游戏Javaswing俄罗斯方块项目源码Javaswing飞机大战游戏源码Javaswing雷电游戏源码Javaswing连连看游戏源码Javaswing模拟写字板源码......
  • Java异常处理的最佳实践
      本文是关于Exception处理的一篇不错的文章,从JavaException的概念介绍起,依次讲解了Exception的类型(Checked/Unchecked),Exception处理的最佳实现:选择Checked还是Unchecked的几个经典依据Exception的封装问题如无必要不要创建自己的Exception不要用Excepti......
  • Java拦截器(Interceptor)详细解析
    转载链接地址:https://www.cnblogs.com/xiaoyh/p/16444681.html一、拦截器概念讲解拦截器的概念之前,我们先看一张图: (1)浏览器发送一个请求会先到Tomcat的web服务器(2)Tomcat服务器接收到请求以后,会去判断请求的是静态资源还是动态资源(3)如果是静态资源,会直接到Tomcat......