springboot springmvc 时区 相差八小时 一小时 夏令时 GMT+8 GMT+08 GMT%2B8 Asia/Shanghai @DateTimeFormat spring.jackson.date-format


1、只管json格式提交和全局返回json时的格式,如果要单独控制某一个时间字段的返回格式使用@JsonFormat(pattern = "HH:mm:ss")

spring:
    jackson:
        date-format: yyyy-MM-dd HH:mm:ss

如果不配置,json方式提交参数时默认的时间格式如下:
yyyy-MM-dd'T'HH:mm:ss.SSSZ
yyyy-MM-dd'T'HH:mm:ss.SSS, EEE
dd MMM yyyy HH:mm:ss zzz
yyyy-MM-dd

2、管时区(不管是form表单提交还是json提交)

spring:
    jackson:
        time-zone: Asia/Shanghai

在Spring程序中配置了spring.jackson.time-zone=GMT+08时,部分时间相差一个小时问题,且是固定的时间出现了固定的时差问题。
经过排查,发现是JVM的默认时区为:Asia/Shanghai,两者不一致,然后Asia/Shanghai 这个时区并不一定与GMT+08这个时区相等,他们是2种定义标准。Asia/Shanghai 这个代表的是中国的时区,但在历史中,有国家(包含中国)政策颁布了在1986-1991年等还存在夏令时。在这样的时间区间,夏季时,会将时间拨快1个小时(即东9区时间),夏季结束时会再次将时间拨回一个小时(即东8区时间)。
所以要保证程序显示的时间没有问题,需要将JVM和spring.jackson.time-zone设置的时区保持一致即可解决问题

用GMT+8前端传1987-05-01 00:00:00,然后再返回给前端会少一个小时。
同样的如果是使用MySQL数据库也会遇到此问题,所以网上很多说连接后面加上serverTimezone=GMT%2B8是不可靠的,改为serverTimezone=Asia/Shanghai就行了

3、只管form-data和x-www-form-urlencoded方式提交

@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")

如果不配置,form表单提交默认的时间格式如下:
yyyy/MM/dd
yyyy/MM/dd HH:mm:ss

4、只管form表单日期提交格式化,下面的方法加到受spring管理的bean里面去,最直接的方式加到main方法类里面

@Bean
public Converter<String, Date> dateConvert() {
    return new Converter<String, Date>() {
        @Override
        public Date convert(String source) {
            String value = source.trim();
            if ("".equals(value)) {
                return null;
            }
            if (source.matches("^\\d{4}-\\d{1,2}$")) {
                return parseDate(source, "yyyy-MM");
            } else if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$")) {
                return parseDate(source, "yyyy-MM-dd");
            } else if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}$")) {
                return parseDate(source, "yyyy-MM-dd HH:mm");
            } else if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}:\\d{1,2}$")) {
                return parseDate(source, "yyyy-MM-dd HH:mm:ss");
            } else if (source.matches("^\\d{4}/\\d{1,2}$")) {
                return parseDate(source, "yyyy/MM");
            } else if (source.matches("^\\d{1,2}:\\d{1,2}:\\d{1,2}$")) {
                return parseDate(source, "HH:mm:ss");
            } else if (source.matches("^\\d{1,2}:\\d{1,2}$")) {
                return parseDate(source, "mm:ss");
            } else if (source.matches("^\\d{4}/\\d{1,2}/\\d{1,2}$")) {
                return parseDate(source, "yyyy/MM/dd");
            } else if (source.matches("^\\d{4}/\\d{1,2}/\\d{1,2} {1}\\d{1,2}:\\d{1,2}$")) {
                return parseDate(source, "yyyy/MM/dd HH:mm");
            } else if (source.matches("^\\d{4}/\\d{1,2}/\\d{1,2} {1}\\d{1,2}:\\d{1,2}:\\d{1,2}$")) {
                return parseDate(source, "yyyy/MM/dd HH:mm:ss");
            } else {
                throw new IllegalArgumentException("Invalid boolean value '" + source + "'");
            }
        }
    };
}

/**
 * 格式化日期
 *
 * @param dateStr String 字符型日期
 * @param format  String 格式
 * @return Date 日期
 */
public Date parseDate(String dateStr, String format) {
    Date date = null;
    try {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        date = simpleDateFormat.parse(dateStr);
    } catch (Exception e) {

    }
    return date;
}

综上总结
一、不管什么方式传参都加上时区统一配置:

spring:
    jackson:
        time-zone: Asia/Shanghai

二、只用json格式接收参数(@RequestBody注解方式)
1、全局统一:

spring:
    jackson:
        date-format: yyyy-MM-dd HH:mm:ss

2、多个时间字段格式各样:
在字段上添加如下主节
@JsonFormat(pattern = "HH:mm:ss")
pattern自定义取值如下(前端高兴就好)
yyyy-MM-dd HH:mm:ss
yyyy/MM/dd HH:mm:ss
yyyy-MM-dd
yyyy/MM/dd
HH:mm:ss
mm:ss
yyyy-MM-dd'T'HH:mm:ss.SSSZ(样例:2020-05-28T22:35:12.000+0800)
yyyy-MM-dd'T'HH:mm:ss.SSS, EEE(样例:2020-05-28T22:35:12.000, 星期四)
dd MMM yyyy HH:mm:ss zzz(样例:28 五月 2020 22:35:12 CST)


三、只用form表单提交
1、返回格式统一:
配置文件添加

spring:
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss

时间字段上添加
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
pattern自定义取值如下(前端高兴就好)
yyyy-MM-dd HH:mm:ss
yyyy/MM/dd HH:mm:ss
yyyy-MM-dd
yyyy/MM/dd
HH:mm:ss
mm:ss
yyyy-MM-dd'T'HH:mm:ss.SSSZ(样例:2020-05-28T22:35:12.000+0800)
yyyy-MM-dd'T'HH:mm:ss.SSS, EEE(样例:2020-05-28T22:35:12.000, 星期四)
dd MMM yyyy HH:mm:ss zzz(样例:28 五月 2020 22:35:12 CST)

2、参数格式和返回格式不统一

@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "HH:mm:ss")

两个pattern自定义取值如上所述

3、重写Converter方式,代码如上所述

四、json方式和form表单方式混合在用
配置文件添加:

spring:
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: Asia/Shanghai

时间字段上添加:

@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")

如果json方式要控制自由格式可将配置中的date-format去掉,然后再字段上添加如下注解:

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")

两个pattern自定义取值如上所述

猜你喜欢

转载自www.cnblogs.com/wkaca7114/p/date.html