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
相关产品推荐
相关产品推荐

