写项目遇到的通用问题

时间类型不一致的问题 前端得到后端的时间数据相差了16个小时 存放进数据库的时间发现与当前系统时间相差了8个小时

这些问题都是时区的问题 对于Java中时区有4个 UTC GMT CSA Asia/shanghai 要知道UTC GMT 和东8区都是有8个小时的时差的。

首先,存放入数据库的时间与当前系统时间相差8个小时,是因为MySQL这些中间件大多默认的是UTC,然后再Java中用new Date(),获取的时间是由当前系统决定的,所以有8个小时的时差,解决方案就是去修改中间件的时区,这里提供的方法是修改配置信息,这里用的是docker容器,且使用了数据卷,所以直接进入mysql的数据卷,在_data目录下新建一个目录,目录名可以随便取,但是后缀必须是.cnf。

接着,由于后端在返回给前端数据时一般用到序列化,然而直接用springboot的默认序列化,采用的也是UTC,所以也有8个时差,加起来前端就16个小时的时差,所以要解决springboot的序列化问题,有三种方式:第一种加注解@JsonFormat 用里面的2个属性值 timezone=GWT+8 这里必须是GWT+8 不能写UTC+8,这是规定,不然识别不了,虽然这2者在数值上差不多;第二种方式是在配置文件里面写,提高复用性,第三种方式就是自定义序列化器 实现这个接口。

package com.atguigu.tingshu.common.config.date;

import com.atguigu.tingshu.common.execption.GuiguException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.deser.std.DateDeserializers;
import com.fasterxml.jackson.databind.ser.std.DateSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.logging.SimpleFormatter;

/**
 * ClassName: CustomerDateHandler
 * Package: com.atguigu.tingshu.common.config.date
 * Description:
 *
 * @Author 陈宇侨
 * @Create 2025/5/11 15:05
 * @Version 1.0
 */
@Component
public class CustomerDateHandler implements Jackson2ObjectMapperBuilderCustomizer {
    @Override
    public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {

        //1.创建时间模版对象
        JavaTimeModule javaTimeModule = new JavaTimeModule();

        //2.对时间格式进行序列化
        javaTimeModule.addSerializer(Date.class,new DateSerializer(){

            //自定义对时间类型做序列化操作
            /**
             *
             * @param value  :指的是序列化的对象里面Date类型的字段以及值
             * @param g      :json生成器:用来负责将数据输出到json中去
             * @param provider  :暂时用不到
             * @throws IOException
             */
            @Override
            public void serialize(Date value, JsonGenerator g, SerializerProvider provider) throws IOException {
//                super.serialize(value, g, provider);
                // 处理时间时区 处理日期时间格式
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT+8"));
                String format = simpleDateFormat.format(value);
                g.writeString(format);
            }
        });

        // 对时间格式进行反序列化
        javaTimeModule.addDeserializer(Date.class,new DateDeserializers.DateDeserializer(){
            /**
             *
             * @param p  Json的解析器
             * @param ctxt
             * @return
             * @throws IOException
             */
            @Override
            public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
                String text = p.getText();
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                dateFormat.setTimeZone(TimeZone.getTimeZone("GMT+8"));
                try {
                    Date parseDate = dateFormat.parse(text);
                    return parseDate;
                } catch (ParseException e) {
                    throw new GuiguException(201,"时间格式不对,无法解析");
                }
            }
        });

        // 将时间模式注册到builder中
        jacksonObjectMapperBuilder.modulesToInstall(javaTimeModule);

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值