SpringBoot中Jackson⽇期的时区和⽇期格式问题
⽬录
1、使⽤场景
因为最近项⽬需要国际化,需要能够⽀持多种国际化语⾔,⽬前需要⽀持三种(法语、英语、简体中⽂)。我们的项⽬部署环境为使⽤阿⾥云(德国)节点。以前我们项⽬主要⽤户在中国国内。⼀部署到德国服务器节点就出现⼀个问题了。数据返回的时间不对,存储的时间也有时差了。此⽂章仅仅与UTC标准时间与北京时间(东⼋区时间)作为实际例⼦。最后跟踪发现,如下⼏点原因:
1.1、数据库MySQL也是有时区的概念的。
通过如下命令可以查询MySQL的时区
show variables like "%time_zone%";
如果未做任何修改会显⽰如下:
+------------------+--------+
| Variable_name | Value |
+------------------+--------+
| system_time_zone | CST |
| time_zone | SYSTEM |
+------------------+--------+
2 rows in set (0.00 sec)
#time_zone说明mysql使⽤system的时区,system_time_zone说明system使⽤CST时区
1.2、系统时区意味着与计算机的操作系统时区相同。
以下是我们北京时间使⽤MySQL时区
set global time_zone = '+8:00'; ##修改mysql全局时区为北京时间,即我们所在的东8区
> set time_zone = '+8:00'; ##修改当前会话时区
> flush privileges; #⽴即⽣效
或者通过修改MySQL的 myf配置⽂件来修改时区
# vim /etc/myf ##在[mysqld]区域中加上
default-time_zone = '+8:00'
# /etc/init.d/mysqld restart ##重启mysql使新时区⽣效
1.2、SpringBoot默认的Json视图转换框架Jackson也有时区概念
Jackson⽇期反序列化时区问题,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.
*<p>
* NOTE: default here does NOT mean JVM defaults but Jackson databindings
* default, usually UTC, but may be changed on <code>ObjectMapper</code>.
*/
public final static String DEFAULT_TIMEZONE = "##default";
值,该值指⽰默认{@链接java.util.TimeZone}
(来⾃反序列化或序列化上下⽂)应使⽤:
注释未定义要使⽤的值。
注意:这⾥的默认值并不意味着JVM默认值,⽽是Jackson数据绑定。
默认值,通常为UTC,但可以在<code>objectmapper<code>上更改。
那个注释已经说明默认情况下会将 时区设置为UTC ,Jackson反序列化时间类型的底层实际上调⽤的是Java的
SimpleDateFormat#parse() ⽅法,⽽JVM中的时区则会根据你的操作系统来获取,所以JVM认为你的时区应该是 GMT+8 时区,⽽要将 UTC 时区的时间转成 GMT+8 时区的时间,就会将你传进来的时间+8个⼩时。
2、代码实现
2.1、解决⽅案⼀下在每个带有⽇期地⽅加上注解
⽇期类型的字段上的 @JsonFormat 加上属性 timezone="GMT+8"
@NotNull
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
@JsonProperty("start_time")
private Date startTime;
此类⽅法需要在包含⽇期地⽅都加上注解属性,⽐较繁琐。
2.2、只需要配置⼀个bean实现整体修改
@Bean
public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() {
return jacksonObjectMapperBuilder ->
jacksonObjectMapperBuilder.TimeZone("GMT+8"));
}
参考⽂章:
2.3、使⽤SpringBoot的配置⽅式
spring.jackson.default-property-inclusion=NON_NULL
spring.jackson.time-zone=GMT+8
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
第⼀个设置就是使⽤24⼩时的时间格式;第⼆个设置就是设置时区为东⼋区。
但是配置时候需要注意
Finally, if you opt out of the Spring Boot default MVC configuration by providing your own @EnableWebMvc configuration, you can take control completely and do everything manually by
springboot中文using getMessageConverters from WebMvcConfigurationSupport.
《Spring Boot Reference Guide》
需要去掉
@EnableWebMvc
参考⽂章:
3、成果展现
经过转换配置转换之后;能够正确的获得和存取对应的时间,建议使⽤
2.2、只需要配置⼀个bean实现整体修改 或者使⽤ 2.3、使⽤SpringBoot的配置⽅式 ⽅式⽐较通⽤性。
其中如果使⽤FastJson转换也可能遇见同样的问题,可以参考⽂章
4、总结
在SpringBoot开发应⽤之中设计⽇期转换需要特别注意,能够主要⽬标能够是的存储和返回的⽇期能够对应上⾃⼰的本地时区。同时能够使⽤较为通⽤的转换⽅式解决相关问题。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论