You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中@JsonFormat标注的Date字段自动添加时间如何解决

解决java.util.Date反序列化后携带时间信息的问题

问题原因

java.util.Date类型本身存储的是精确到毫秒的时间戳,你看到的Sun Jul 05 05:30:00 IST 1998是Date的toString()方法按系统默认时区格式化后的输出结果。你当前加的@JsonFormat注解没有指定时区,Jackson默认使用UTC时区解析日期字符串,和你服务所在的IST时区存在时差,导致解析后出现非预期的时间部分。

解决方案(无需修改Date类型为LocalDate)

方案1:补全@JsonFormat注解的时区配置

直接在现有@JsonFormat注解中指定和你服务一致的时区即可解决时区偏移问题,示例如下:

@JsonFormat(shape = JsonFormat.Shape.STRING,pattern = "yyyy-MM-dd", timezone = "Asia/Kolkata")
public Date date;

该方案仅保证反序列化时的日期和传入一致,Date对象本身仍会保留时间部分(当前时区的0点),如果需要彻底清空时间部分可采用方案2。

方案2:自定义Date反序列化器,清空时间部分

自定义Jackson反序列化器,解析日期后主动将时分秒毫秒置为0:

  1. 首先编写自定义反序列化类:
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

public class DateOnlyDeserializer extends StdDeserializer<Date> {
    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
    static {
        // 指定对应时区
        DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));
        DATE_FORMAT.setLenient(false);
    }

    public DateOnlyDeserializer() {
        super(Date.class);
    }

    @Override
    public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
        String dateStr = jsonParser.getText().trim();
        try {
            Date parsedDate = DATE_FORMAT.parse(dateStr);
            // 清空时间部分
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(parsedDate);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);
            return calendar.getTime();
        } catch (ParseException e) {
            throw new RuntimeException("日期格式非法,请传入yyyy-MM-dd格式的字符串:" + dateStr);
        }
    }
}
  1. 在date字段上添加反序列化器绑定注解:
@JsonFormat(shape = JsonFormat.Shape.STRING,pattern = "yyyy-MM-dd", timezone = "Asia/Kolkata")
@JsonDeserialize(using = DateOnlyDeserializer.class)
public Date date;

方案3:SpringBoot项目全局配置

如果项目中大量存在此类只需要日期的Date类型字段,可以直接在项目配置文件中全局指定Jackson的日期格式和时区,无需单独给字段加注解:
application.yml配置示例:

spring:
  jackson:
    date-format: yyyy-MM-dd
    time-zone: Asia/Kolkata

补充说明

java.util.Date本身没有时区属性,输出时的时间信息是调用toString()方法按JVM默认时区格式化的结果,只要确保Date对应的时间戳为当日0点,即可满足你仅保留日期的需求。

内容的提问来源于stack exchange,提问作者snacks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 22:45:05