конвертировать xmlGregorianCalendar в дату и обратно - PullRequest
0 голосов
/ 29 марта 2019

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

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

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

@ Entity

public class example{
String string;
ObjectExample object;
}

@ Entity

public class ObjectExample{
String oneString;
Date date;
}

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

1 Ответ

1 голос
/ 31 марта 2019

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

  • Поскольку ваша переменная называется 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();

И другиеway:

    // It doesn’t 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 нам нужно вручную установить неиспользуемые поля как неопределенные, что делает его многословным.

Заключение

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

...