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

Java 如何将XMLGregorianCalendar仅与日期部分(日、月、年)进行比较?,java,web-services,xsd,jaxb,gregorian-calendar,Java,Web Services,Xsd,Jaxb,Gregorian Calendar,我正在开发一个与spring struts web应用程序集成的web服务,在XSD中有一个XMLGregorianCalendar类型的属性,假设属性名为trxDate 在SOAPUI测试应用程序中,如果我使用:2013-02-21插入trxDate的值,那么我发送soap xml请求数据,并使用:System.out.println(trxDate)方法打印服务方法中的值,打印输出结果与输入的结果相同:2013-02-21 现在,我正在尝试创建一个函数,将trxDate与当前日期进行比较。我

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

在SOAPUI测试应用程序中,如果我使用:2013-02-21插入trxDate的值,那么我发送soap xml请求数据,并使用: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-02-20

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

int result = trxDate.compare(xgc);
结果是2,这意味着:不确定(来自DatatypeConstants类)。正确的结果应为-1、0或1


那么我的代码有什么问题吗?

更新

您还可以通过以下方式创建
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(字符串词汇表示法)
演示

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
试一试

这是对XMLGregorianCalendar的一个提示(命令),在时间未定义的情况下使用
xsd:date
类型解释了它使用javadoc链接到的进行比较

B.1节。比较算法的第二部分规定,两个日期时间必须定义完全相同的{年、月、日、小时、分钟、秒}字段(子)集。如果他们不这样做,结果是不确定的。(XML模式规范在算法描述中使用
来指示不确定的结果。)


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

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


如果要使用
newXMLGregorianCalendar(lexicalRepresentation)

以防有人仍在寻找替代方案,那么这就避免了再次往返字符串的过程。这正是适合我的要求

    ...

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

这将删除时区和时间戳。

哇,我不知道有这样的方法,非常快速和简单。非常感谢。但是我想知道,如果用我上面的代码方式,是否有可能达到同样的结果?哇,我很困惑有很多种方式,你的方式和Ian的方式哪一种更好?哇,我很困惑有很多种方式,你的方式和Blaise的方式哪一种更好?我刚刚试过你的代码,有点错误,您需要将+1添加到
xgc.setMonth()
,因此代码应该是:
xgc.setMonth(now.get(Calendar.MONTH)+1)。似乎XMLGregorianCalendar使用了一个月的指数。在我的书中,这是一个很好的答案。我遇到这个问题是因为我比较了2个XMLGregorianCalendar实例,但其中一个设置了时区。将它们转换为GregorianCalendar对象并使用compareTo()方法为我提供了我正在寻找的比较逻辑。否则,使用XMLGregorianCalendar的compare()方法将始终返回DatatypeConstants.Undeterminate。
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);
    ...

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