SpringBoot+Vue前后端日期时间格式统一的解决方案

在 SpringBoot和Vue 前后端分离项目中,常见的问题之一就是日期时间格式不统一、参数转换失败、时区时差错乱。前台传参报错、后台返回时间格式异常、数据库存储时间和中国时区不对应,大多是因为未统一配置日期解析规则和时区。

一、SpringBoot Date 日期格式化

后端数据库查询出的 Date 类型数据,默认返回给前台是时间戳或默认格式字符串,可读性差。SpringBoot 提供局部注解和全局配置两种格式化方式,按需选择即可。

方式1:局部配置

适用于仅部分字段需要自定义时间格式的场景,直接在实体类 Date 字段上添加 @JsonFormat 注解,指定格式和东八区时区,避免时差问题。

import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;

/**
 * 实体类时间字段局部格式化
 */
private Date createTime;

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") //使用北京时间
public Date getCreateTime() {
    return createTime;
}

方式2:全局配置

适用于项目全局统一时间格式的场景,无需逐个字段加注解,直接在配置文件中配置 Jackson 全局时间规则,所有 Date 类型出参自动格式化。

application.yml 配置:

spring:
  jackson:
    # 统一时区为东八区
    time-zone: GMT+8
    # 全局日期格式化格式
    date-format: yyyy-MM-dd HH:mm:ss

二、String 自动转 Date

Vue 日期组件传递到后台的参数为字符串格式,直接绑定 Date 类型参数会抛出经典异常:

Failed to convert property value of type ‘java.lang.String’ to required type ‘java.util.Date’ for property ‘beginCreateTime’;

解决方案是通过 Spring MVC 的 Converter 自定义字符串转日期转换器,支持多种主流时间格式自动解析,兼容常规时间格式、ISO标准时间格式。

import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 全局日期字符串转Date转换器
 * 解决前台String时间参数转后台Date类型失败问题
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        // 支持的所有时间格式,可根据业务拓展
        List<String> patterns = Arrays.asList(
                "yyyy-MM-dd HH:mm:ss",       // 常规年月日时分秒
                "yyyy-MM-dd",                // 常规年月日
                "yyyy-MM-dd'T'HH:mm:ss.SSSX",// ISO标准格式(带毫秒)
                "yyyy-MM-dd'T'HH:mm:ssX"     // ISO标准格式(无毫秒)
        );

        // 注册String转Date转换器
        registry.addConverter(new Converter<String, Date>() {
            @Override
            public Date convert(String source) {
                // 遍历所有格式,匹配成功则转换
                for (String pattern : patterns) {
                    try {
                        return new SimpleDateFormat(pattern).parse(source);
                    } catch (ParseException ignored) {
                        // 匹配失败则继续下一种格式
                    }
                }
                throw new RuntimeException("时间格式转换失败,非法时间字符串:" + source);
            }
        });
    }
}

三、Vue前端日期时间组件适配

前端使用 Element Plus 日期范围选择器时,组件绑定的是时间数组,无法直接传给后台,需要拆分字段,同时指定固定时间格式,保证和后端解析规则统一。

1、页面组件代码

<el-form-item label="创建时间">
  <el-date-picker
      v-model="createTimeRange"
      type="datetimerange"
      value-format="YYYY-MM-DD HH:mm:ss"
      range-separator="至"
      start-placeholder="开始时间"
      end-placeholder="结束时间"
  />
</el-form-item>

2、请求参数处理逻辑

将日期范围数组拆分为开始时间和结束时间两个独立字段,适配后台接收参数:

const loadData = () => {
  // 拷贝查询参数
  const params = {...userQuery.value}
  // 拆分时间范围数组为开始、结束时间
  params.beginCreateTime = createTimeRange.value?.[0]
  params.endCreateTime = createTimeRange.value?.[1]
  // 发起请求
  userApi.list(params).then(result => {
    list.value = result.data.records
    total.value = result.data.total
  })
}

四、MySQL时区时差8小时问题

很多项目前后端时间格式正常,但存入数据库时间偏差8小时,核心原因是 serverTimezone 配置不当,这里详细说明两种配置的区别和适用场景。

  • serverTimezone=UTC:MySQL 以UTC世界标准时间为基准。后端JVM北京时间(UTC+8)存入数据库时,会自动减去8小时,导致数据库时间少8小时。
  • serverTimezone=Asia/Shanghai:MySQL 以北京时间为基准。后端JVM北京时间直接存入,时间无偏差,适配国内业务。

国内业务:推荐配置 serverTimezone=Asia/Shanghai,无需转换时差,开发效率高,时间展示无偏差。
出海/跨境业务:推荐配置 serverTimezone=UTC,统一全球时间基准,适配多地区时区展示。

THE END
文章版权归Tinsur.cn所有,转载分享请标注原链接
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容