如何将XMLGregorianCalendar与日期部分(日,月,年)进行比较?

时间:2013-02-20 11:07:31

标签: java web-services xsd jaxb gregorian-calendar

我正在开发一个集成了spring-struts web应用程序的web服务,在XSD中有一个XMLGregorianCalendar类型属性,假设属性名称是 trxDate

在SOAPUI测试应用程序中,如果我将trxDate的值插入: 2013-02-21 ,那么我发送了soap xml请求数据,并在service方法中打印了值:System。 out.println(trxDate)方法,打印输出结果与输入的相同:2013-02-21。

现在,我正在尝试创建一个函数来将 trxDate 与当前日期进行比较。我知道我们可以使用trxDate.compare(currentDate)方法对它进行比较。问题是我不知道如何使用当前日期创建XMLGregorianCalendar对象集,仅使用日期部分(日,月和年)进行比较。

我尝试使用此代码:

    GregorianCalendar gc = new GregorianCalendar();
    gc.set(GregorianCalendar.HOUR_OF_DAY, 0);
    gc.set(GregorianCalendar.MINUTE, 0);
    gc.set(GregorianCalendar.SECOND, 0);
    gc.set(GregorianCalendar.MILLISECOND, 0);

    XMLGregorianCalendar xgc = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
    System.out.println(xgc);

结果是:
2013-02-20T00:00:00.000 + 07:00

但我期待着:
2013年2月20日

如果使用日期( xgc )与 trxDate 进行比较:

int result = trxDate.compare(xgc);

结果为2,表示:INDETERMINATE(来自DatatypeConstants类)。正确的结果应该是-1,0或1。

我的代码出了什么问题?

5 个答案:

答案 0 :(得分:4)

javadoc for XMLGregorianCalendar.compare解释说它使用rules from the XML Schema specification进行比较,javadoc链接到该比较。

B.1节。比较算法的结果表明,两个dateTimes必须具有完全相同(子)的{year,month,day,hour,minute,second}字段集。如果他们不这样做,结果是不确定的。 (XML Schema规范在算法描述中使用<>来表示不确定的结果。)

因此,如果您有一个仅定义了年,月和日的XMLGregorianCalendar,则必须将其与另一个定义了年,月和日的XMLGregorianCalendar进行比较。您必须像Blaise建议的那样从字符串中解析它,或者您必须实例化XMLGregorianCalendar并自行调用setYearsetMonthsetDay

答案 1 :(得分:4)

而不是尝试清除GregorianCalendar中不需要的字段,可能更容易创建未初始化的XMLGregorianCalendar,然后只复制所做的字段想:

XMLGregorianCalendar xgc = DatatypeFactory.newInstance().newXMLGregorianCalendar();
GregorianCalendar now = new GregorianCalendar();
xgc.setYear(now.get(Calendar.YEAR));
xgc.setMonth(now.get(Calendar.MONTH) + 1);
xgc.setDay(now.get(Calendar.DAY_OF_MONTH));
System.out.println(xgc);

如果您使用newXMLGregorianCalendar(lexicalRepresentation)

,这可以避免往返String并再次返回

答案 2 :(得分:2)

<强>更新

您也可以这样创建XMLGregorianCalendar

    XMLGregorianCalendar xgc = df.newXMLGregorianCalendar(
            2012, 
            DatatypeConstants.FEBRUARY, 
            21, 
            DatatypeConstants.FIELD_UNDEFINED, 
            DatatypeConstants.FIELD_UNDEFINED, 
            DatatypeConstants.FIELD_UNDEFINED, 
            DatatypeConstants.FIELD_UNDEFINED, 
            DatatypeConstants.FIELD_UNDEFINED);
    System.out.println(xgc);

您可以使用以下方法:

  • newXMLGregorianCalendar(String lexicalRepresentation)

<强>演示

import javax.xml.datatype.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        DatatypeFactory df = DatatypeFactory.newInstance();

        XMLGregorianCalendar xgc = df.newXMLGregorianCalendar("2013-02-12");
        System.out.println(xgc);
    }

}

<强>输出

2013-02-12

答案 3 :(得分:0)

尝试

    String str = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
    XMLGregorianCalendar xgc = DatatypeFactory.newInstance().newXMLGregorianCalendar(str);
    System.out.println(xgc);

这是XMLGregorianCalendar的提示(顺序),以便在时间未定义时使用xsd:date类型

答案 4 :(得分:0)

万一有人还在寻找替代品。这正是我的要求。

    ...

    date.setTimezone(DatatypeConstants.FIELD_UNDEFINED);
    date.setTime(DatatypeConstants.FIELD_UNDEFINED,
            DatatypeConstants.FIELD_UNDEFINED,
            DatatypeConstants.FIELD_UNDEFINED,
            DatatypeConstants.FIELD_UNDEFINED);
    ...

这将删除时区和时间戳。