2013-02-20 3 views
3

Я разрабатываю веб-сервис, интегрированный с веб-приложением Spring-struts, в XSD существует свойство типа XMLGregorianCalendar, скажем, имя свойства trxDate.Как сравнить XMLGregorianCalendar с только частью даты (день, месяц, год)?

В применении тестирования SoapUI, если я вставил значение trxDate с: 2013-02-21, то я послал данные запроса мыла XML, и я напечатал значение в методе обслуживания с: System.out.println (trxDate), результат распечатки такой же, как и введенный: 2013-02-21.

Теперь, я пытаюсь создать функцию для сравнения trxDate с текущей датой. Я знаю, что мы можем сравнить его с помощью метода trxDate.compare (currentDate). Проблема в том, что я не могу создать объект XMLGregorianCalendar с текущей датой только с помощью части Date (день, месяц и год), которая будет использоваться для сравнения.

Я пытался с этим кодом:

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

Эй, я так смущен, что есть много способов, которые лучше между вашим путем и способом Блейза? – null

+0

Я просто пробовал свой код, есть ошибка, вам нужно добавить +1 в 'xgc.setMonth()', поэтому код должен стать: 'xgc.setMonth (now.get (Calendar.MONTH) + 1); '. Кажется, XMLGregorianCalendar использует одномесячный индекс. – null

+1

@suud thanks, я отредактировал ответ, чтобы исправить это. –

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 (String lexicalRepresentation)

Demo

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

+0

Эй, я так смущен, что есть много способов, которые лучше между твоим путем и способом Иана? – null

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. алгоритма сравнения утверждает, что оба параметра даты должны иметь точно такой же (под) набор {год, месяц, день, час, минуту, второй}. Если они этого не сделают, результат будет неопределенным. (Спецификация схемы XML использует <> в описании алгоритма для указания неопределенного результата.)

Итак, если у вас есть XMLGregorianCalendar с указанием только года, месяца и дня, вы должны сравнить его с другим XMLGregorianCalendar с помощью всего лишь года, месяца и день. Либо вы должны разобрать его из строки, как предложил Блейз, либо вы должны создать экземпляр XMLGregorianCalendar и позвонить по телефону setYear, setMonth и setDay.

+1

Это был отличный ответ в моей книге. Я столкнулся с этой проблемой, потому что я сравнивал 2 экземпляра XMLGregorianCalendar, но у одного был установлен часовой пояс. Преобразование их в объекты GregorianCalendar и использование метода compareTo() предоставило мне логику сравнения, которую я искал. В противном случае метод compare() XMLGregorianCalendar всегда будет возвращать DatatypeConstants.INDETERMINATE. – Carlos

Смежные вопросы