日期时间参数,格式配置(SpringBoot)
作者:mmseoamin日期:2023-12-14

介绍

在SpringBoot项目中,接口中的日期和时间类型的参数,配置格式。

日期格式

接口中常用的日期时间格式有两种:

  1. 字符串(比如:yyyy-MM-dd HH:mm:ss)
  2. 时间戳(比如:1696839876955)

这两种方式各有优势。

  • 字符串格式表示时间,直观清晰,便于识别出时间。但是,字符串格式存在时区问题,需要在字段中描述出时区(SpringMVC的默认时间格式中带有时区),或者前后端规定好默认时区,比如东八区(GMT+8)。
  • 时间戳,用数字表示时间,准确定位时间,不存在时区问题。缺点是,不够直观,无法直接识别出时间戳对应的具体时间(需要转换),不便于从接口直接判断时间是否正确,测试比较费时费力。

    格式配置

    日期参数的格式,可以配置。分为:全局配置和局部配置。

    • 全局配置:作用于项目全局的时间参数。
    • 局部配置:只作用于配置的字段,覆盖全局配置,其余字段不受影响。

      全局配置

      Query时间入参,使用字符串

      配置

      spring:
        mvc:
          format:
            # Query参数,时间格式(转换 java.util.Date)
            date: yyyy-MM-dd HH:mm:ss
      

      Query参数实体示例

      Query参数,使用 java.util.Date 类型接收。

      package com.example.web.exception.query;
      import com.example.core.validation.phone.query.PhoneQuery;
      import io.swagger.v3.oas.annotations.media.Schema;
      import lombok.Data;
      import org.springdoc.api.annotations.ParameterObject;
      import java.util.Date;
      @Data
      @ParameterObject
      @Schema(name = "用户Query")
      public class UserQuery {
          // 其他字段
          @Schema(description = "开始时间", example = "2023-01-01 08:30:00")
          private Date beginTime;
          @Schema(description = "结束时间", example = "2023-12-31 17:00:00")
          private Date endTime;
      }
      

      接口调用成功

      日期格式正确,接口调用成功。

      在这里插入图片描述

      打印日志:

      查询用户列表。userQuery=UserQuery(name=null, phone=null, beginTime=Sun Jan 01 08:30:00 GMT+08:00 2023, endTime=Sun Dec 31 17:00:00 GMT+08:00 2023, beginDate=null, endDate=null),pageQuery=PageQuery(pageNumber=1, pageSize=10)

      接口调用失败

      接口输入必须符合格式,否则会调用失败(报出异常)。

      在这里插入图片描述

      Body时间入参和响应时间出参

      默认响应中的时间参数,会转换成字符串,默认时间格式举例:

      2023-10-10T01:31:03.279+00:00

      配置

      目标格式为:yyyy-MM-dd HH:mm:ss,东八区。

      spring:
        jackson:
          # Body参数和响应,时间格式(转换 java.util.Date)
          date-format: yyyy-MM-dd HH:mm:ss
          time-zone: GMT+8
      

      Body时间入参:UserEditParam

      package com.example.web.response.model.param;
      import com.example.core.validation.phone.strict.Phone;
      import com.fasterxml.jackson.annotation.JsonFormat;
      import io.swagger.v3.oas.annotations.media.Schema;
      import lombok.Data;
      import javax.validation.constraints.Email;
      import javax.validation.constraints.NotBlank;
      import javax.validation.constraints.NotEmpty;
      import java.util.Date;
      @Data
      @Schema(name = "编辑用户Param")
      public class UserEditParam {
          // 其他字段
          @JsonFormat(pattern = "yyyy-MM-dd")
          @Schema(description = "开始日期", example = "2023-01-01")
          private Date beginDate;
          @JsonFormat(pattern = "yyyy-MM-dd")
          @Schema(description = "结束日期", example = "2023-12-31")
          private Date endDate;
      }
      

      效果

      接口调用:

      在这里插入图片描述

      控制台打印参数:

      新增用户,Post请求。param=UserAddParam(name=张三, phone=18612345678, email=zhangsan@example.com, beginTime=Sun Jan 01 08:30:00 CST 2023, endTime=Sun Dec 31 17:00:00 CST 2023)

      响应时间出参:UserVO

      package com.example.web.model.vo;
      import io.swagger.v3.oas.annotations.media.Schema;
      import lombok.Data;
      import java.util.Date;
      @Data
      @Schema(name = "用户VO")
      public class UserVO {
          // 其他字段
          @Schema(description = "开始时间", example = "2023-01-01 01:20:30")
          private Date beginTime;
          @Schema(description = "结束时间", example = "2023-01-01 01:20:30")
          private Date endTime;
      }
      

      效果

      在这里插入图片描述

      响应时间出参:时间戳

      配置

      spring:
        jackson:
          serialization:
            # 时间字段(java.util.Date),返回时间戳。注意,此配置会覆盖掉 spring.jackson.date-format 。
            write-dates-as-timestamps: true
      

      效果

      响应时间出参,为时间戳格式。

      在这里插入图片描述

      局部配置

      Query时间入参:局部格式

      Query时间入参,如果某个字段需要的时间格式和全局不相同,可以配置这个字段的自定义的入参格式。

      使用注解:@DateTimeFormat

      配置示例

      package com.example.web.exception.query;
      import com.example.core.validation.phone.query.PhoneQuery;
      import io.swagger.v3.oas.annotations.media.Schema;
      import lombok.Data;
      import org.springdoc.api.annotations.ParameterObject;
      import org.springframework.format.annotation.DateTimeFormat;
      import java.util.Date;
      @Data
      @ParameterObject
      @Schema(name = "用户Query")
      public class UserQuery {
          // 其他字段
          @DateTimeFormat(pattern = "yyyy-MM-dd")
          @Schema(description = "开始日期", example = "2023-01-01")
          private Date beginDate;
          @DateTimeFormat(pattern = "yyyy-MM-dd")
          @Schema(description = "结束日期", example = "2023-12-31")
          private Date endDate;
      }
      

      效果

      在这里插入图片描述

      Body时间入参:局部格式

      使用注解:@JsonFormat

      配置示例

      package com.example.web.response.model.param;
      import com.example.core.validation.phone.strict.Phone;
      import com.fasterxml.jackson.annotation.JsonFormat;
      import io.swagger.v3.oas.annotations.media.Schema;
      import lombok.Data;
      import javax.validation.constraints.Email;
      import javax.validation.constraints.NotBlank;
      import javax.validation.constraints.NotEmpty;
      import java.util.Date;
      @Data
      @Schema(name = "编辑用户Param")
      public class UserEditParam {
          // 其他字段
          @JsonFormat(pattern = "yyyy-MM-dd")
          @Schema(description = "开始日期", example = "2023-01-01")
          private Date beginDate;
          @JsonFormat(pattern = "yyyy-MM-dd")
          @Schema(description = "结束日期", example = "2023-12-31")
          private Date endDate;
      }
      

      效果

      在这里插入图片描述

      编辑用户,PUT请求。id=1234567890123456789,param=UserEditParam(name=张三, phone=18612345678, email=zhangsan@example.com, beginDate=Sun Jan 01 00:00:00 CST 2023, endDate=Sun Dec 31 00:00:00 CST 2023)

      问题

      注意:如下图传递参数,接口也能调用成功。

      接口收到的参数,只包含年月日。

      编辑用户,PUT请求。id=1234567890123456789,param=UserEditParam(name=张三, phone=18612345678, email=zhangsan@example.com, beginDate=Sun Jan 01 00:00:00 CST 2023, endDate=Sun Dec 31 00:00:00 CST 2023)

      在这里插入图片描述

      在这里插入图片描述

      响应时间出参:局部格式

      使用注解:@JsonFormat

      配置示例

      package com.example.web.model.vo;
      import com.fasterxml.jackson.annotation.JsonFormat;
      import io.swagger.v3.oas.annotations.media.Schema;
      import lombok.Data;
      import java.util.Date;
      @Data
      @Schema(name = "用户VO")
      public class UserVO {
          // 其他字段
          @JsonFormat(pattern = "yyyy-MM-dd")
          @Schema(description = "开始日期", example = "2023-01-01")
          private Date beginDate;
          @JsonFormat(pattern = "yyyy-MM-dd")
          @Schema(description = "结束日期", example = "2023-12-31")
          private Date endDate;
      }
      

      效果

      在这里插入图片描述