конвертировать xmlGregorianCalendar в дату и обратно

у меня все, у меня есть приложение весенней загрузки. что я хочу в частности, это преобразовать класс (который имеет поле nestet объект) в его соответствующей сущности. пример:

 public class example{
String string;
ObjectExample object;
}
public class ObjectExample{
String oneString;
XMLGregorianCalendar date;
}

эти 2 объекта также помечены в другом пакете как сущности, но, как правило, в ObjectExampleEntity у меня есть Date date вместо XMLGregorianCalendar, как в примере

@Сущность

public class example{
String string;
ObjectExample object;
}

@Сущность

public class ObjectExample{
String oneString;
Date date;
}

Поскольку у меня есть большая модель и большая сущность (это только пример) с множеством вложенных классов, я использую dozer для преобразования из модели в класс. Например, рассмотрим, что репозиторий jpa создается только для класса-отца. Я хочу знать, как я могу с dozer конвертировать из даты (лица) в XMLGregorianCalendar (модель) и обратно. модель и сущность, повторяю, равны. единственная разница заключается в типе даты. Спасибо

0
источник поделиться
1 ответ

Я предполагаю:

  • Поскольку ваша переменная имеет имя date она содержит календарную дату (без времени суток).
  • Вы связаны с XMLGregorianCalendar из-за того, что WSDL находится вне вашего контроля, но вы можете изменить тип на стороне объекта.

Исходя из этих предположений, я рекомендую LocalDate на стороне объекта. Он является частью java.time, современного Java-API даты и времени, и представляет собой точную дату без времени суток. Используемый вами класс Date плохо разработан, давно устарел и не рекомендуется. Кроме того, несмотря на название Date никогда не представляла дату, но момент времени.

Есть еще варианты. Я представляю три.

Вариант 1: перенести отдельные поля

От XMLGregorianCalendar до LocalDate:

    DatatypeFactory xmlFactory = DatatypeFactory.newInstance();
    XMLGregorianCalendar wsDate = xmlFactory
            .newXMLGregorianCalendarDate(2019, DatatypeConstants.MARCH, 30,
                    DatatypeConstants.FIELD_UNDEFINED);

    // Validate
    if ((wsDate.getHour() != 0 && wsDate.getHour() != DatatypeConstants.FIELD_UNDEFINED)
            || (wsDate.getMinute() != 0 && wsDate.getMinute() != DatatypeConstants.FIELD_UNDEFINED)
            || (wsDate.getSecond() != 0 && wsDate.getSecond() != DatatypeConstants.FIELD_UNDEFINED)
            || (wsDate.getMillisecond() != 0 && wsDate.getMillisecond() != DatatypeConstants.FIELD_UNDEFINED)) {
        System.out.println("Warning: time of day will be lost in conversion");
    }
    if (wsDate.getTimezone() != DatatypeConstants.FIELD_UNDEFINED) {
        System.out.println("Warning: UTC offset will be lost in conversion");
    }

    // Convert
    LocalDate entityDate = LocalDate.of(wsDate.getYear(), wsDate.getMonth(), wsDate.getDay());
    System.out.println(entityDate);

Вывод в этом случае:

2019-03-30

От LocalDate до XMLGregorianCalendar:

    LocalDate entityDate = LocalDate.of(2019, Month.MARCH, 31);

    XMLGregorianCalendar wsDate = xmlFactory.newXMLGregorianCalendarDate(
            entityDate.getYear(),
            entityDate.getMonthValue(),
            entityDate.getDayOfMonth(),
            DatatypeConstants.FIELD_UNDEFINED);
    System.out.println(wsDate);

2019-03-31

Преимущество этого способа: это довольно просто. Недостаток: вы и ваш читатель должны следить за тем, чтобы поля были указаны в правильном порядке.

Вариант 2: конвертировать через строки

    // Validate as before

    // Convert
    LocalDate entityDate = LocalDate.parse(wsDate.toXMLFormat());

Результат как и прежде.

    XMLGregorianCalendar wsDate
            = xmlFactory.newXMLGregorianCalendar(entityDate.toString());

Преимущество: кратко, и нет ничего удивительного в том, что результаты верны. Недостаток: для меня это похоже на трату времени на форматирование в строку только для ее анализа.

Вариант 3: конвертировать через GregorianCalendar и ZonedDateTime

    ZonedDateTime zdt = wsDate.toGregorianCalendar().toZonedDateTime();

    // Validate
    if (! zdt.toLocalTime().equals(LocalTime.MIN)) {
        System.out.println("Warning: time of day will be lost in conversion");
    }
    if (! zdt.getZone().equals(ZoneId.systemDefault())) {
        System.out.println("Warning: UTC offset will be lost in conversion");
    }

    // Finish conversion
    LocalDate entityDate = zdt.toLocalDate();

И другой способ:

    // It doesnt matter which time zone we pick
    // since we are discarding it after conversion anyway
    ZonedDateTime zdt = entityDate.atStartOfDay(ZoneOffset.UTC);
    GregorianCalendar gCal = GregorianCalendar.from(zdt);
    XMLGregorianCalendar wsDate = xmlFactory.newXMLGregorianCalendar(gCal);
    wsDate.setTime(DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED,
            DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED);
    wsDate.setTimezone(DatatypeConstants.FIELD_UNDEFINED);

Валидация, которую я здесь представляю, немного проще, но не совсем строгая. Если вы хотите строгой проверки, вы можете просто использовать проверку из ранее.

Преимущества: я думаю, что это официальный путь; по крайней мере, он использует предложенные методы преобразования. Что мне нравится, так это то, что само преобразование является прямым и кратким. Недостаток: при преобразовании в XMLGregorianCalendar нам нужно установить неиспользуемые поля неопределенными вручную, что делает его многословным.

Заключение

Я представил три варианта, каждый со своими плюсами и минусами. Вы также можете смешивать, конечно, но использование одинакового преобразования в обоих случаях, вероятно, менее запутанно в конце.

+1
источник

Посмотрите другие вопросы по меткам или Задайте вопрос