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

java.util.Calendar返回儒略日期而非公历的异常问题

问题分析与解决

问题根源

你遇到的是日期反序列化时的历法匹配错误:请求中的2024-04-09 11:50:54是公历(格里高利历)格式,但框架将其反序列化为java.util.Calendar时,默认使用了儒略历(Julian Calendar)解析,导致年份被错误转换——2024年在儒略历规则下被解析成了公元14年,最终出现不符合预期的日期输出。

java.util.Calendar作为抽象类,其默认实现(如GregorianCalendar)虽支持两种历法,但未明确指定时,解析逻辑可能因框架配置或默认行为切换到儒略历,引发此类问题。

解决方案

方案1:替换为Java 8+日期API(优先推荐)

java.util.Calendar属于老旧API,设计存在诸多缺陷,建议直接使用java.time包下的日期类替代,从根源避免历法混淆:

  1. 修改DTO类:
import java.time.LocalDateTime;
public class ImportExportProgressDTO {
    private LocalDateTime prolongedDate;
}
  1. 输出逻辑无需额外处理:
public void update(ImportExportProgressDTO importExportProgressDTO){
    System.out.println(importExportProgressDTO.getProlongedDate());
}

LocalDateTime会自动按公历解析请求中的日期字符串,输出结果与请求一致。

方案2:强制Calendar使用格里高利历(兼容旧代码)

如果必须保留java.util.Calendar,需在反序列化阶段明确指定历法:

  1. 字段级注解配置(以Jackson框架为例):
import java.util.Calendar;
import com.fasterxml.jackson.annotation.JsonFormat;
public class ImportExportProgressDTO {
    @JsonFormat(
        pattern = "yyyy-MM-dd HH:mm:ss",
        timezone = "UTC",
        calendar = java.util.GregorianCalendar.class
    )
    private Calendar prolongedDate;
}
  1. 全局配置(Spring MVC环境):
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.GregorianCalendar;

@Configuration
public class JacksonConfig {
    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setCalendarDeserializers(new com.fasterxml.jackson.databind.deser.std.CalendarDeserializer(GregorianCalendar.class));
        return mapper;
    }
}

通过上述配置,框架会强制用格里高利历解析日期,避免儒略历转换错误。

方案3:手动修正已错误解析的Calendar(临时补救)

若已拿到错误的Calendar对象,可手动转换为格里高利历:

public void update(ImportExportProgressDTO importExportProgressDTO){
    Calendar wrongCalendar = importExportProgressDTO.getProlongedDate();
    GregorianCalendar correctCalendar = new GregorianCalendar();
    correctCalendar.setTime(wrongCalendar.getTime());
    // 强制启用格里高利历模式
    correctCalendar.setGregorianChange(new Date(Long.MIN_VALUE));
    System.out.println(correctCalendar.getTime());
}

此方式仅作临时补救,不建议作为长期解决方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 05:55:04