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

Java字符串转XMLGregorianCalendar日期结果不符问题求助

问题根因

你的代码出现日期大幅偏差,是三个错误叠加导致的:

  • 日期格式模式符大小写完全写错:SimpleDateFormat中模式符大小写敏感,你写的YYYY代表周历年而非公历年(公历年用小写yyyy),DD代表当年的第几天而非月内日期(月内日期用小写dd),这两个错误直接导致解析出的年、日数值完全错乱。
  • 格式模式和输入字符串不匹配:你要解析的输入是带时间、时区偏移的ISO 8601格式字符串(2022-04-13T09:54:54-04:00),但你的格式模式只写了年、月、日部分,剩余的时间、时区内容会被SimpleDateFormat按本地默认时区随意解析,进一步放大了日期偏差。
  • 转换逻辑没有做字段截断:你直接把完整带时间、时区的日历对象转成XMLGregorianCalendar,默认会输出全量时间字段,根本不可能得到你想要的仅年-月-日格式结果。
正确实现方案

优先使用Java 8引入的java.time日期API做解析,从根源避免老日期API的各种坑,代码如下:

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import java.time.OffsetDateTime;
import java.util.GregorianCalendar;

public class Main {
    public static void main(String[] args) throws DatatypeConfigurationException {
        // 直接解析ISO8601标准格式的日期字符串,无需自定义格式器
        OffsetDateTime dateTime = OffsetDateTime.parse("2022-04-13T09:54:54-04:00");
        GregorianCalendar calendar = GregorianCalendar.from(dateTime);

        XMLGregorianCalendar xmlGregCal = DatatypeFactory.newInstance().newXMLGregorianCalendar(calendar);
        // 清空时分秒、毫秒、时区字段,仅保留年月日
        xmlGregCal.setTime(
                DatatypeConstants.FIELD_UNDEFINED,
                DatatypeConstants.FIELD_UNDEFINED,
                DatatypeConstants.FIELD_UNDEFINED,
                DatatypeConstants.FIELD_UNDEFINED
        );
        xmlGregCal.setTimezone(DatatypeConstants.FIELD_UNDEFINED);

        System.out.println(xmlGregCal);
        // 输出:2022-04-13,完全符合预期
    }
}

如果你必须兼容JDK 7及更早版本,只能使用SimpleDateFormat的话,必须把格式模式修正为和输入串完全匹配的yyyy-MM-dd'T'HH:mm:ssXXX,解析得到Date对象后,后续转日历、截断字段的逻辑和上面示例一致。注意SimpleDateFormat是线程不安全的,多线程场景下必须做同步处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 15:48:23