Thymeleaf为何将LocalDate从yyyy-MM-dd转为dd/MM/yyyy格式?
为什么日期会变成dd/MM/yyyy格式?
Thymeleaf渲染LocalDate时,默认会跟随应用的**区域设置(Locale)**进行格式化。如果你的应用Locale是使用日/月/年格式的(比如en_GB、部分地区的zh_CN),Thymeleaf就会自动把LocalDate转成dd/MM/yyyy格式输出。但浏览器的<input type="date">只接受yyyy-MM-dd的标准格式,所以就会抛出格式不匹配的错误。
你后台打印显示yyyy-MM-dd是因为LocalDate的toString()方法默认就是这个格式,但Thymeleaf渲染表单时用的是Spring的格式化机制,和直接打印的逻辑不一样。
不用自定义格式化器的简单解决方法
方法1:实体类字段加@DateTimeFormat注解(推荐)
直接在实体类的dob字段上添加@DateTimeFormat注解,指定格式化模式为yyyy-MM-dd,这样Spring在处理数据绑定和Thymeleaf渲染时都会统一用这个格式:
import java.time.LocalDate; import org.springframework.format.annotation.DateTimeFormat; public class User { // 替换成你的实体类名 // 其他字段... @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate dob; // 对应的getter、setter方法 }
表单代码保持不变:
<span>Date of Birth*:</span> <input type="date" th:field="*{dob}" class="form-control mb-4" placeholder="Date of Birth">
方法2:手动绑定value和name(不修改实体类)
如果不想改动实体类,可以放弃th:field的双向绑定,手动用th:value设置显示值,同时指定name属性保证提交时能映射到后台字段:
<span>Date of Birth*:</span> <input type="date" name="dob" th:value="${#temporals.format(dob, 'yyyy-MM-dd')}" class="form-control mb-4" placeholder="Date of Birth">
注意:提交时Spring需要将yyyy-MM-dd格式的字符串转成LocalDate,Spring Boot 2.0+默认已经支持这种转换,无需额外配置。
关于#temporals的错误原因
你之前尝试th:field="*{#temporals.format(dob, 'yyyy-MM-dd')}"报错,是因为th:field是双向绑定表达式,要求对应实体类的属性(这里是LocalDate类型的dob),但#temporals.format()返回的是字符串,和实体类的属性类型不匹配,所以Spring会认为找不到对应的属性 getter/setter,抛出错误。#temporals工具类本身没问题(只要你引入了thymeleaf-extras-java8time依赖),但不能用在th:field的表达式里。
内容的提问来源于stack exchange,提问作者Sam

