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

Java中java.util.Date类型DOB插入数据库始终为1970-01-01求助

出生日期(DOB)存入数据库始终为1970-01-01的解决方法

问题背景

Postman固定请求JSON格式如下:

{
  "DOB":"20101123"
}

预期存入数据库的日期格式为2010-11-23,但实际每次都会存入1970-01-01,且项目限制无法修改java.util.Date数据类型。

问题原因

DTO类EmployeeInformation中DOB字段为java.util.Date类型,但请求传递的是**yyyyMMdd格式的字符串日期**。Jackson默认的日期解析器无法识别这种格式,解析失败后会生成时间戳为0的Date对象,对应日期就是1970-01-01。

解决方案

方案1:添加日期格式化注解(最简单直接)

在EmployeeInformation的DOB字段上添加@JsonFormat注解,指定输入日期的格式:

@Data
public class EmployeeInformation {
    // 其他字段保持不变...

    @JsonProperty(value = "DOB")
    @JsonFormat(pattern = "yyyyMMdd", timezone = "GMT+8") // 时区根据业务需求调整
    private Date DOB;
}

添加该注解后,Jackson会按照指定格式解析字符串,生成正确的Date对象,存入数据库后就是预期的日期。

方案2:自定义日期反序列化器(注解不适用时使用)

如果注解方式无法满足特殊需求,可以自定义反序列化逻辑:

  1. 编写自定义反序列化器类:
public class CustomDateDeserializer extends StdDeserializer<Date> {
    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMdd");

    public CustomDateDeserializer() {
        this(null);
    }

    public CustomDateDeserializer(Class<?> vc) {
        super(vc);
    }

    @Override
    public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
        String dateStr = jsonParser.getText();
        try {
            return DATE_FORMAT.parse(dateStr);
        } catch (ParseException e) {
            throw new RuntimeException("日期格式错误,需为yyyyMMdd格式", e);
        }
    }
}
  1. 在DTO的DOB字段上指定使用该反序列化器:
@JsonProperty(value = "DOB")
@JsonDeserialize(using = CustomDateDeserializer.class)
private Date DOB;

额外检查项

  • 确认数据库表的dob字段类型为DATE,避免因字段类型不匹配导致存储异常
  • 检查Updater类的更新逻辑:如果存在新旧日期equals判断不生效的情况(比如时间精度问题),需要单独处理Date类型的比较:
    修改Updater的update方法中的判断逻辑:
    public <T> Updater update(String fieldName,
                              Function<EmployeeInformation, T> newValueGetter,
                              Function<OrgEmployeeMap, T> oldValueGetter,
                              BiConsumer<OrgEmployeeMap, T> oldValueSetter) {
      final var newValue = newValueGetter.apply(information);
      final var oldValue = oldValueGetter.apply(existing);
      
      if (newValue == null) {
        return this;
      }
      
      // 针对Date类型单独处理比较逻辑
      if (newValue instanceof Date && oldValue instanceof Date) {
        Date newDate = (Date) newValue;
        Date oldDate = (Date) oldValue;
        
        Calendar newCal = Calendar.getInstance();
        newCal.setTime(newDate);
        Calendar oldCal = Calendar.getInstance();
        oldCal.setTime(oldDate);
        
        // 仅比较年、月、日是否一致
        boolean sameDate = newCal.get(Calendar.YEAR) == oldCal.get(Calendar.YEAR)
                && newCal.get(Calendar.MONTH) == oldCal.get(Calendar.MONTH)
                && newCal.get(Calendar.DAY_OF_MONTH) == oldCal.get(Calendar.DAY_OF_MONTH);
                
        if (sameDate) {
          return this;
        }
      } else if (newValue.equals(oldValue)) {
        return this;
      }
      
      this.updatedFields.add(fieldName);
      oldValueSetter.accept(existing, newValue);
      return this;
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 01:54:53