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

SpringBoot JUnit ExpectedDatabase测试中SimpleDateFormat日期解析异常

日期解析出现1799年偏差的原因及解决办法

问题场景

测试预期的XML数据中日期为:

<VEH_DATE_MEC="1800-01-01"/>

执行以下代码解析日期后:

SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd");
isoFormat.setTimeZone(TimeZone.getTimeZone("GMT+1"));
Date date = isoFormat.parse("1800-01-01");
vehiculeFrontDto.setDatePremiereImmat(date);

Setter方法实现:

public void setDatePremiereImmat(Date datePremiereImmat) {
    this.datePremiereImmat = DateCopyUtils.copyDate(datePremiereImmat);
}

调试发现date变量的实际值为:Tue Dec 31 23:00:00 UTC 1799,测试断言失败:

  • 预期值:<1[800-01-01]>
  • 实际值:<1[799-12-31 23:00:00.0]>

问题原因

  1. 旧日期API的历史时区缺陷:SimpleDateFormat和Date是Java早期的日期处理类,对1900年之前的历史时区规则支持存在bug。1800年时还没有统一的GMT+1时区偏移标准,SimpleDateFormat依赖的旧时区数据在计算时,错误地将1800-01-01 GMT+1转换为UTC时间1799-12-31 23:00:00。
  2. 时区上下文不一致:测试断言时以UTC时区展示实际日期值,而预期值是不带时区的纯日期,两者时区基准不同,导致日期看起来偏差一天。

解决办法

方案1:改用Java 8+的java.time新日期API(推荐)

新API彻底修复了旧类的历史时区问题,设计更严谨:

// 解析纯日期,无需考虑时区
LocalDate targetDate = LocalDate.parse("1800-01-01");

// 若需兼容旧代码中的Date类型:
Date utilDate = Date.from(targetDate.atStartOfDay(ZoneId.of("GMT+1")).toInstant());
vehiculeFrontDto.setDatePremiereImmat(utilDate);

如果业务仅需日期信息,建议直接用LocalDate存储,完全规避时区干扰。

方案2:修复旧API的使用逻辑

若必须继续使用SimpleDateFormat,可通过以下方式调整:

  • 统一解析和断言的时区:要么解析时不设置GMT+1时区,要么断言时用GMT+1时区格式化实际值,确保和预期值的时区基准一致:
SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd");
// 使用和断言逻辑一致的时区(或默认时区)
Date date = isoFormat.parse("1800-01-01");
  • 更新JDK时区数据:升级JDK到包含最新tzdata的版本,修复旧日期的时区计算bug,但这种方式不如换用新API彻底。

方案3:调整测试断言逻辑

如果测试仅关心日期部分(忽略时间和时区),可将实际值和预期值都转换为纯日期字符串后再对比:

// 用GMT+1时区格式化实际日期,得到1800-01-01
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
formatter.setTimeZone(TimeZone.getTimeZone("GMT+1"));
String actualDateStr = formatter.format(vehiculeFrontDto.getDatePremiereImmat());
// 对比actualDateStr和"1800-01-01"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 14:10:21