如何用XMLGregorianCalendar精准输出9999-99-99?解决日期转换错误
问题分析与解决方案
首先,咱们得搞清楚为什么你传入9999-99-99会得到10007-07-08——这是因为GregorianCalendar的核心设计是处理符合现实格里高利历法的合法日期,它会自动把超出范围的字段(比如99月、99日)转换成合法的日期:
- 99个月会被拆解成8年零3个月(12×8=96,99-96=3),所以年份从9999变成9999+8=10007
- 剩下的3个月对应GregorianCalendar的0基月份(3→4月),再加上99天:4月30天+5月31天+6月30天=91天,99-91=8,最终日期落到7月8日
- 这一系列自动滚动计算后,就得到了
10007-07-08
要实现精准输出9999-99-99,你需要绕过GregorianCalendar的自动调整逻辑,直接构造XMLGregorianCalendar对象,有两种简单的方法:
方法1:直接用字符串构造
利用DatatypeFactory的字符串参数版本方法,直接传入你需要的日期格式字符串(即使字段超出常规范围):
import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; public class XMLGregorianCalendarDemo { public static void main(String[] args) { XMLGregorianCalendar xmlDate = null; try { // 直接传入XML Schema兼容的日期字符串 xmlDate = DatatypeFactory.newInstance().newXMLGregorianCalendar("9999-99-99"); } catch (Exception e) { e.printStackTrace(); } System.out.println("XMLGregorianCalendar :- " + xmlDate); } }
方法2:手动设置字段
手动给XMLGregorianCalendar的每个字段赋值,注意这里的月份是1基的(和GregorianCalendar的0基不同),所以直接传99即可:
import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; public class XMLGregorianCalendarDemo { public static void main(String[] args) { XMLGregorianCalendar xmlDate = null; try { xmlDate = DatatypeFactory.newInstance().newXMLGregorianCalendar(); xmlDate.setYear(9999); xmlDate.setMonth(99); // XMLGregorianCalendar月份是1基,无需调整 xmlDate.setDay(99); } catch (Exception e) { e.printStackTrace(); } System.out.println("XMLGregorianCalendar :- " + xmlDate); } }
两种方法运行后都会输出你需要的9999-99-99,核心就是避免使用会自动调整日期的GregorianCalendar来构造对象,直接操作XMLGregorianCalendar的原始字段。
内容的提问来源于stack exchange,提问作者InfinityCoder
相关产品推荐
相关产品推荐

