4

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

在 SOAPUI 测试应用程序中,如果我将 trxDate 的值插入为:2013-02-21,然后我发送了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,这意味着: INDETERMINATE(来自 DatatypeConstants 类)。正确的结果应该是 -1、0 或 1。

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

4

5 回答 5

5

与其尝试从 中清除不需要的字段,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);

这样可以避免往返 String 并再次返回,如果您使用newXMLGregorianCalendar(lexicalRepresentation)

于 2013-02-20T11:37:09.867 回答
4

XMLGregorianCalendar.compare的javadoc解释说它使用XML Schema 规范中的规则进行比较,javadoc 链接到这些规则。

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

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

于 2013-02-20T11:29:06.810 回答
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(字符串词法表示)

演示

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
于 2013-02-20T11:20:37.247 回答
1

尝试

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

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

于 2013-02-20T11:24:07.783 回答
0

以防有人仍在寻找替代方案。这符合我的要求。

    ...

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

这将删除时区和时间戳。

于 2019-11-09T03:45:50.997 回答