15 时间格式的转换

15 时间格式的转换

|-------------|------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------|---|
| 方向 | 技术 | 控制方式 | 关键点 |
| 前端 → 后端 | 表单提交 (application/x-www-form-urlencoded) | 1.注解 :@DateTimeFormat(pattern = "yyyy-MM-dd") 2.全局配置 :spring.mvc.format.date=yyyy-MM-dd 3. 代码定制 : addFormatters中重写Formatter的parse(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-dd和spring.jackson.time-zone=GMT+8 | 后端可以定义任意友好的展示格式,前端直接接收字符串并展示。Formatter对此场景无效 。 |
| 后端 → 前端 | 视图渲染 (如 Thymeleaf, JSP) | 代码定制 : addFormatters中重写Formatter的print(Date, Locale) 方法 | 后端可以定义任意格式。当Date对象被直接渲染到视图模板时,Spring MVC 会使用此方法将其格式化为指定字符串。这是Formatter独有的场景,用于统一页面上所有日期的显示格式。 |

注:对于Jackson库可以换成其他Json库,比如Fastjson,此时注解@JsonFormat应该换成Fastjson对应的@JSONField 注解。换了之后,除了注解和库变了,其他的规则同@JsonFormat。如何换库,具体见 ++14 SpringBoot整合SpringMVC++14.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;
         }
     });

    }

  4. 后端可以定义任意格式。

相关推荐
九月生5 小时前
基于 Sa-Token 实现 API 接口签名校验(Spring Boot 3 实战)
web安全·springboot
程序员龙语6 小时前
HTML&CSS 基础入门笔记:样式引入、选择器与图片格式
状态模式
消失的旧时光-19437 小时前
从命令式跳转到声明式路由:前端、Android、Flutter 的一次统一演进
android·前端·flutter·状态模式
syt_10137 小时前
设计模式之-状态模式
javascript·设计模式·状态模式
Yeniden1 天前
Deepeek用大白话讲解 --> 状态模式(企业级场景1,自动售货机2,订单状态3,消除if-else4)
java·开发语言·状态模式
带刺的坐椅1 天前
超越 SpringBoot 4.0了吗?OpenSolon v3.8, v3.7.4, v3.6.7 发布
java·ai·springboot·web·solon·flow·mcp
hgz07101 天前
Spring Boot自动配置
java·springboot
驱动探索者2 天前
[缩略语大全]之[编译器]篇
计算机·状态模式·飞书·编译器
TimberWill2 天前
MinIO整合SpringBoot实现获取文件夹目录结构及文件内容
java·linux·springboot
yy我不解释2 天前
关于comfyui的token顺序打乱(三)
python·ai作画·flask·状态模式·comfyui