15 时间格式的转换

15 时间格式的转换

方向
技术
控制方式
关键点
前端 → 后端
表单提交 (application/x-www-form-urlencoded)
1.注解@DateTimeFormat(pattern = "yyyy-MM-dd")
2.全局配置spring.mvc.format.date=yyyy-MM-dd
3. 代码定制
addFormatters中重写Formatterparse(String,Locale)方法
后端解析格式必须与前端发送的字符串格式一致。三种方式均可,优先级:注解 > 代码定制 > 全局配置。
前端 → 后端
JSON 提交 (@RequestBody)
1.注解
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
2.全局配置
spring.jackson.date-format=yyyy-MM-dd
spring.jackson.time-zone=GMT+8
后端解析格式必须与 JSON 中的字符串格式一致。Formatter对此场景无效
后端 → 前端
JSON 响应 (@ResponseBody)
1.注解
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
2.全局配置spring.jackson.date-format=yyyy-MM-ddspring.jackson.time-zone=GMT+8
后端可以定义任意友好的展示格式,前端直接接收字符串并展示。Formatter对此场景无效
后端 → 前端
视图渲染 (如 Thymeleaf, JSP)
代码定制
addFormatters中重写Formatterprint(Date, Locale)方法
后端可以定义任意格式。当Date对象被直接渲染到视图模板时,Spring MVC 会使用此方法将其格式化为指定字符串。这是Formatter独有的场景,用于统一页面上所有日期的显示格式。
注:对于Jackson库可以换成其他Json库,比如Fastjson,此时注解@JsonFormat应该换成Fastjson对应的@JSONField 注解。换了之后,除了注解和库变了,其他的规则同@JsonFormat。如何换库,具体见 14 SpringBoot整合SpringMVC14.2.3。

15.1 前端 → 后端 (表单提交)

  1. 场景:用户通过

    标签提交数据,其中包含日期。

  2. 前端行为: 会将日期以 yyyy-MM-dd 格式的字符串发送给后端。
  3. 后端解析方式:
  • 方式一 (全局配置):在 application.yml 中配置 spring.mvc.format.date。
spring:
  mvc:
    format:
      date: yyyy-MM-dd # 必须与前端传来的格式一致
  • 方式二 (局部注解):在实体类的日期字段上使用 @DateTimeFormat 注解。
public class User {
    @DateTimeFormat(pattern = "yyyy-MM-dd") // 必须与前端传来的格式一致
    private Date birthday;
    // ...
}
  • 方式三(代码定制):创建一个配置类实现WebMvcConfigurer接口,并在重写addFormatters这个方法。修改这个方法中的 Formatter 的 parse(String, Locale) 方法。
  1. 优先级:@DateTimeFormat 注解 (局部) > 代码定制 > spring.mvc.format.date (全局)。
  2. 结论:如果你想使用除 yyyy-MM-dd 之外的格式(例如 yyyy/MM/dd),你必须在前端通过 JavaScript 将日期字符串格式化为你想要的格式,然后再提交给后端。后端的配置或注解必须与前端最终发送的格式保持一致。

15.2 前端 → 后端 (JSON 提交)

  1. 场景:前端通过 AJAX (如 fetch, axios) 发送 JSON 数据给后端,后端使用 @RequestBody 注解接收。
  2. 前端行为:前端构造一个 JSON 对象,其中日期是一个字符串,例如 {"username": "张三", "birthday": "2025-11-19"}。
  3. 后端解析方式:
  • 方式一 (全局配置):在 application.yml 中配置 Jackson 的日期格式。
spring:
  jackson:
    date-format: yyyy-MM-dd # 必须与 JSON 中的日期字符串格式一致
    time-zone: GMT+8
  • 方式二 (局部注解):在实体类的日期字段上使用 @JsonFormat 注解。
public class User {
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") // 必须与 JSON 中的日期字符串格式一致
    private Date birthday;
    // ...
}
  1. 优先级:@JsonFormat 注解 (局部) > spring.jackson.date-format (全局)。
  2. 错误示例:如果 JSON 中的日期是 "2025-11-19",而你的配置或注解是 yyyy/MM/dd,就会遇到下面这个提到的错误:
JSON parse error: Cannot deserialize value of type `java.util.Date` from String "2025-11-19": expected format "yyyy/MM/dd"

15.3 后端 → 前端 (JSON 响应)

  1. 场景:后端通过 @ResponseBody 注解返回一个 Java 对象(如 User),Spring Boot 会自动将其转换为 JSON 字符串。
  2. 后端行为:Spring Boot 使用 Jackson 库进行序列化。
  3. 控制 JSON 格式的方式:
  • 方式一 (全局配置):在 application.yml 中配置 spring.jackson.date-format。这会影响所有 Date 类型字段的序列化。
  • 方式二 (局部注解):在实体类的日期字段上使用 @JsonFormat 注解。这只影响该字段的序列化。
  1. 注意:后端到前端 日期格式想是什么就是什么 都可以正常转。
  2. 原因:在这个场景中,后端是 “格式的定义者”。Jackson 会按照你指定的格式(通过 @JsonFormat 或全局配置),将 Date 对象转换成一个字符串。前端接收到的就是这个格式化好的字符串,它不需要进行任何解析,直接展示即可。

15.4 后端 → 前端(视图渲染)

  1. 场景:后端 Controller 方法返回一个逻辑视图名称(如 "user/profile")和一个包含 Date 对象的模型(Model)。Spring MVC 会将模型数据传递给视图模板(如 Thymeleaf, FreeMarker, JSP)进行渲染,最终生成 HTML 页面返回给前端。
  2. 后端行为:Spring MVC 在将模型中的 Date 对象传递给视图模板之前,会检查是否存在一个注册的 Formatter。如果存在,它会调用该格式化器的 print 方法。
  3. 控制日期显示格式的方式:
方式一 (全局代码配置):通过实现 WebMvcConfigurer 接口并重写 addFormatters 方法,注册一个自定义的 Formatter。在该格式化器的 print(Date date, Locale locale) 方法中,定义你希望的日期字符串格式(如 "yyyy年MM月dd日")。
@Override
public void addFormatters(FormatterRegistry registry) {
    registry.addFormatter(new Formatter<Date>() {
        @Override
        public String print(Date date, Locale locale) {
            // 当Date对象被渲染到视图时,格式化为 "yyyy年MM月dd日"
            return new SimpleDateFormat("yyyy年MM月dd日").format(date);
        }

        // parse方法在此场景下不发挥作用
        @Override
        public Date parse(String text, Locale locale) throws ParseException {
            return null;
        }
    });
}
  1. 后端可以定义任意格式。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值