2013-02-20 121 views
3

我正在开发一个与spring-struts web应用程序集成的webservice,在XSD中有一个XMLGregorianCalendar类型属性,假设属性名称为trxDate。在SOAPUI测试应用程序中,如果我将trxDate的值插入:然后我发送了soap xml请求数据,并在服务方法中打印了值:System.out.println( trxDate)方法,打印输出结果与输入的结果相同:2013-02-21。如何比较XMLGregorianCalendar只有日期部分(日,月,年)?

现在,我试图创建一个函数来比较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,表示INDETERMINATE(来自DatatypeConstants类)。正确的结果应该是-1,0或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)

+0

哇,我很困惑,有很多方法,在你的方式和Blaise的方式之间更好? – null 2013-02-21 03:47:42

+0

我刚刚试过你的代码,有一点错误,你需要为'xgc.setMonth()'添加+1,所以代码应该变成:'xgc.setMonth(now.get(Calendar.MONTH)+ 1);'。看来XMLGregorianCalendar使用基于一个月的索引。 – null 2013-02-21 04:03:02

+1

@suud谢谢,我编辑了解决这个问题的答案。 – 2013-02-21 08:09:51

2

UPDATE

你也可以创建你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(字符串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 
+1

哇,我不知道有这样的方法,非常快速和容易。非常感谢。但是我想知道如果使用我的代码方式,是否有可能实现相同的结果? – null 2013-02-20 11:24:57

+0

哇,我很困惑,有很多方法,在你的方式和伊恩的方式之间更好? – null 2013-02-21 03:46:28

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

javadoc for XMLGregorianCalendar.compare解释说,它使用rules from the XML Schema specification作为比较,javadoc链接。

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

所以,如果你有一个刚刚年,月,日的的XMLGregorianCalendar定义,你必须用刚刚年,月,另一个的XMLGregorianCalendar它比较日定义。您必须按照Blaise的建议,从字符串中解析它,或者您必须实例化一个XMLGregorianCalendar,并自己调用setYear,setMonthsetDay

+1

在我的书中,这是一个很好的答案。我遇到了这个问题,因为我正在比较2个XMLGregorianCalendar实例,但其中一个具有设置的时区。将它们转换成GregorianCalendar对象,并使用compareTo()方法为我提供了我正在寻找的比较逻辑。否则,使用XMLGregorianCalendar的compare()方法将始终返回DatatypeConstants.INDETERMINATE。 – Carlos 2013-11-28 06:30:12

相关问题