Гость
Map
Форумы / Java [игнор отключен] [закрыт для гостей] / Rest Controller как вернуть дату с timeZone / 6 сообщений из 6, страница 1 из 1
08.12.2020, 00:09
    #40025441
Timein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Rest Controller как вернуть дату с timeZone
Добрый вечер. Помогите, пожалуйста, разобраться с датами:
У меня есть довольно простой контроллер
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
@RestController
@Slf4j
public class TimeTestController {
    @PostMapping("/time-test")
    public @ResponseBody TimeTestRs timeTest (@RequestBody TimeTestRq timeTest) {
        log.info("request {}",  timeTest);
        TimeTestRs time = new TimeTestRs();
        time.setDate(timeTest.getDate());
        return time;
    }
}



И простой класс
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TimeTestRq {
    private String id;
    private Date date;
}


@Data
@AllArgsConstructor
@NoArgsConstructor
public class TimeTestRs {
    private String id;
    private Date date;
}


Когда я пытаюсь вызвать контроллер и передать ему дату в формате 2020-12-07T19:54:25.860+0100, я получаю в логе дату с timeZone UTC. И метод post мне тоже возвращает UTC, а мне надо вернуть дату ровно в том формате и виде, который у меня пришел (с +0100)
Мне подсказали, что надо заменить Date на OffsetDateTime, но когда я переписал класс TimeTestRq c date на OffsetDateTime, я стал получать ошибку
nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.time.OffsetDateTime` from String "2020-12-07T19:54:25.860+0100": Failed to deserialize java.time.OffsetDateTime: (java.time.format.DateTimeParseException) Text '2020-12-07T19:54:25.860+0100' could not be parsed, unparsed text found at index 26

Как можно это исправить?
...
Рейтинг: 0 / 0
08.12.2020, 01:52
    #40025450
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Rest Controller как вернуть дату с timeZone
Timein

а мне надо вернуть ... ровно в том формате и виде, который у меня пришел (с +0100)

String
...
Рейтинг: 0 / 0
08.12.2020, 01:59
    #40025452
Андрей Панфилов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Rest Controller как вернуть дату с timeZone
Timein

Когда я пытаюсь вызвать контроллер и передать ему дату в формате 2020-12-07T19:54:25.860+0100, я получаю в логе дату с timeZone UTC. И метод post мне тоже возвращает UTC, а мне надо вернуть дату ровно в том формате и виде, который у меня пришел (с +0100)
Мне подсказали, что надо заменить Date на OffsetDateTime, но когда я переписал класс TimeTestRq c date на OffsetDateTime, я стал получать ошибку
nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.time.OffsetDateTime` from String "2020-12-07T19:54:25.860+0100": Failed to deserialize java.time.OffsetDateTime: (java.time.format.DateTimeParseException) Text '2020-12-07T19:54:25.860+0100' could not be parsed, unparsed text found at index 26

Как можно это исправить?


Добро пожаловать в чудный мир передачи ISO8601 по REST. Если посмотреть как jackson определяет десериализатор для OffsetDateTime, то там будет так:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
    public static final InstantDeserializer<OffsetDateTime> OFFSET_DATE_TIME = new InstantDeserializer<>(
            OffsetDateTime.class, DateTimeFormatter.ISO_OFFSET_DATE_TIME,
            OffsetDateTime::from,
            a -> OffsetDateTime.ofInstant(Instant.ofEpochMilli(a.value), a.zoneId),
            a -> OffsetDateTime.ofInstant(Instant.ofEpochSecond(a.integer, a.fraction), a.zoneId),
            (d, z) -> d.withOffsetSameInstant(z.getRules().getOffset(d.toLocalDateTime())),
            true // yes, replace zero offset with Z
    );



Вот этот вот DateTimeFormatter.ISO_OFFSET_DATE_TIME хочет чтобы в смещении часы, минуты (и секунды) были разделены двоеточием:
Код: java
1.
static final OffsetIdPrinterParser INSTANCE_ID_Z = new OffsetIdPrinterParser("+HH:MM:ss", "Z");



Строго говоря они правы, а вам время передают в неправильном формате: согласно ISO8601 формат может быть либо basic (без разделителей вообще), либо extended (со всеми разделителями), а у вас получается mixed: в дате и времени разделители есть (- и :), а в смещении уже нет.

Собственно если на клиенте нет возможности исправить поведение, то нужно описывать собственный формат, парсер для него и десериализатор.
...
Рейтинг: 0 / 0
08.12.2020, 10:21
    #40025502
Timein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Rest Controller как вернуть дату с timeZone
Leonid Kudryavtsev, не очень понял, что именно надо смотреть


Андрей Панфилов,Андрей ПанфиловСтрого говоря они правы, а вам время передают в неправильном формате: согласно ISO8601 формат может быть либо basic (без разделителей вообще), либо extended (со всеми разделителями), а у вас получается mixed: в дате и времени разделители есть (- и :), а в смещении уже нет.
То есть строка должна быть вида: 2020-12-07T19:54:25.860+01:00?
Поменял Date date на OffsetDateTime offsetDateTime
И в конроллере time.setOffsetDateTime(timeTest.getOffsetDateTime());
Ошибка пропала, но в выводе я получаю UTC и вместо зоны Z 2020-12-07T18:54:25.860Z
...
Рейтинг: 0 / 0
08.12.2020, 10:35
    #40025506
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Rest Controller как вернуть дату с timeZone
Timein,
Rest это API.
Или попросту говоря это методы с параметрами.
Поэтому как договоритесь, так дату и передавайте. Это специфический тип.
Если клиент учебное заведение, то rest передает так как написано в расписании 12:21.
Ну или можете несколько форматов сразу передать. Как строку, с таймзоной и без нее.
...
Рейтинг: 0 / 0
08.12.2020, 10:39
    #40025507
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Rest Controller как вернуть дату с timeZone
Timein,
Ну и проверьте на соответствие java8. Там куча изменений по классам в датах.
Вплоть до номеров месяцев с нуля))))
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Rest Controller как вернуть дату с timeZone / 6 сообщений из 6, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]