Jackson/Spring 1900年日期格式化异常(相差5分钟)
问题
在开发过程中,遇到1900-01-08,格式为yyyy-MM-dd,接口返回的却总是少一天,变成了1900-01-07,导致页面显示不正确。
排查
因为使用了jackson的@JsonFormat注解,第一反应是时区不对,但经测试,调整时区并无效果,切2022-10-10等普通日期是可以正常显示的。然后将格式化精确到秒,发现只差5分钟,这就令人非常费解了,网上查到的资料也比较凌乱。
接口返回的数据是没问题的,便将思路放在了json格式上,最后经过单元测试,确认是Jackson的问题。结合资料和Debug,Jackson默认的日期格式化类是SimpleDateFormat,在测试了Jackson、jdk、hutool等日期工具后,确认SimpleDateFormat存在异常。
测试代码如下:
public static void test() throws JsonProcessingException, ParseException {String str = "1900-01-08 00:00:00";Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(str);System.out.println("date:" + date + "\n");// date:Mon Jan 08 00:00:00 CST 1900StdDateFormat format = new StdDateFormat();System.out.println("std:" + format.format(date));// std:1900-01-07T15:54:17.000+00:00SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println("simple:" + dateFormat.format(date));// simple:1900-01-08 00:00:00System.out.println("DateUtil:" + DateUtil.formatDateTime(date));// DateUtil:1900-01-08 00:00:00System.out.println();ObjectMapper objectMapper = new ObjectMapper();objectMapper.setDateFormat(dateFormat);System.out.println(objectMapper.writer().writeValueAsString(date));// "1900-01-08 00:00:00"
}
解决方案
方案一
数据库的日期直接存12点。通过拦截器或硬编码,在保存/编辑的时候处理数据。
tip:实现难度低,侵入性强,不推荐
方案二
自定义@jsonformat的日期解析器,解决这个bug。
tip:实现难度高,不推荐
方案三(推荐)
全局Jackson配置,指定日期处理器,并去掉字段上面的@JsonFormat
tip:实现难度低,侵入度低,但是无法再使用注解自定义格式,如果全局统一格式的话,建议采用此方法。
配置代码如下:
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {/*** 统一日期格式化** @return void*/@Overridepublic void configureMessageConverters(List> converters) {MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();ObjectMapper objectMapper = new ObjectMapper();// 指定日期格式化工具objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));jackson2HttpMessageConverter.setObjectMapper(objectMapper);converters.add(0, jackson2HttpMessageConverter);}}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
