REST API POST提交Date类型参数入库自动生成时间戳问题咨询
问题解答
疑问1:自动生成的时间戳来源及原因
这个额外的时间部分来自Jackson反序列化的默认逻辑 + 时区偏移两个环节的共同作用:
- 你传入的请求体中是
dd-MM-yyyy格式的日期字符串,Spring MVC底层用Jackson将字符串反序列化为java.sql.Date对象时,会默认给日期补充当前JVM所在时区的零点时间,生成对应的毫秒级时间戳。 - 入库或查询展示时,时间戳会根据数据库/服务的时区转换,最终显示出你看到的
05:30:00部分。你出现的fromWhen年份变成2014的问题,大概率是Jackson的日期解析格式配置错误,比如把dd-MM-yyyy错配为MM-dd-yyyy或者yy-MM-dd,导致日期字段解析错乱。
疑问2:对java.sql.Date的认知是否正确
你的认知部分正确但存在遗漏:
- 设计层面
java.sql.Date确实是为了仅存储日期,官方要求它会把时分秒毫秒都设置为0,但这个清零操作是针对JVM默认时区的,而且它本质继承了java.util.Date,内部始终持有完整的毫秒时间戳,并没有真正丢弃时间部分。 - 本次出现带时间戳的结果,常见原因有3种:
- 你没有在POJO的日期字段上添加
@Temporal(TemporalType.DATE)注解,JPA实现(如Hibernate)会默认将java.sql.Date识别为时间戳类型入库,保留完整时间信息。 - 数据库对应字段的类型是
DATETIME/TIMESTAMP而非DATE,就算传入的是仅带日期的对象,数据库也会自动补全时间部分存储。 - 查询时数据库驱动或ORM框架会将DATE类型的值转换为带默认时间的日期对象返回,展示时带出了时间部分。
- 你没有在POJO的日期字段上添加
修复方案
- 优先推荐Java 8+项目使用
java.time.LocalDate类型替换java.sql.Date,该类型是不可变的,本身不携带时间和时区信息,从根源避免该问题。 - 如果要继续使用
java.sql.Date,按以下步骤调整:- 给两个日期字段添加注解明确类型:
@Column(name = "TO_WHEN") @Temporal(TemporalType.DATE) @JsonFormat(pattern = "dd-MM-yyyy", timezone = "你需要的时区,比如GMT+8") private Date toWhen; @Column(name = "FROM_WHEN") @Temporal(TemporalType.DATE) @JsonFormat(pattern = "dd-MM-yyyy", timezone = "你需要的时区,比如GMT+8") private Date fromWhen;- 检查数据库对应字段类型,确认是
DATE类型而非带时间的日期类型。 - 全局配置Jackson的日期序列化规则,避免格式解析错误。
内容的提问来源于stack exchange,提问作者Ayush Mishra
相关产品推荐
相关产品推荐

