MessageConversionException при сопоставлении даты строки с LocalDateTime

У меня есть очередь, которая слушает тему, и мой слушатель получает DTO. Мне нужно разобрать строку, чтобыLocalDateTime но я получаю эту ошибку

org.springframework.messaging.converter.MessageConversionException: Could not read JSON: Text '2020-06-18 11:12:46' could not be parsed at index 10

Вот подробности сообщения

{"id":444, "details":{"TYPE":[1]},"dateOccurred":"2020-06-18 11:12:46"}"] 

И вот как я установил это в моем DTO

public class PlanSubscriptionDto {
    private Long id;

    private Map<String, List<Long>> details;

    private LocalDateTime dateOccurred;

    public void setDateOccurred(String dateTime) {
        this.dateOccurred = LocalDateTime.parse(dateTime, DateTimeFormatter.ISO_DATE_TIME);
//ive also tried this
//this.dateOccurred = LocalDateTime.parse(dateTime, DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG));
    }
}

Спасибо за помощь! Любой совет был бы замечательным.

2 ответа

Решение

Используйте строку шаблона формата, чтобы определить формат.

public class PlanSubscriptionDto {
    private static final DateTimeFormatter FORMATTER
            = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");

    private Long id;

    private Map<String, List<Long>> details;

    private LocalDateTime dateOccurred;

    public void setDateOccurred(String dateTime) {
        this.dateOccurred = LocalDateTime.parse(dateTime, FORMATTER);
    }
}

Почему ваш код не работал?

Формат ISO 8601 имеет Tмежду датой и временем. Нет никакихT в строке даты и времени, поэтому DateTimeFormatter.ISO_DATE_TIME не может его разобрать.

Варианты

Итак, мы подошли к делу, я хотел бы показать еще пару вариантов. Вкус разный, поэтому не могу сказать, какой из них вам больше понравится.

Вы можете вставить Tдля получения формата ISO 8601. Тогда вам не понадобится явное средство форматирования. Один аргументLocalDateTime.parse() анализирует формат ISO 8601.

    public void setDateOccurred(String dateTime) {
        dateTime = dateTime.replace(' ', 'T');
        this.dateOccurred = LocalDateTime.parse(dateTime);
    }

Или придерживаясь средства форматирования и промежутка между датой и временем, мы можем определить средство форматирования более многословным способом:

    private static final DateTimeFormatter FORMATTER = new DateTimeFormatterBuilder()
            .append(DateTimeFormatter.ISO_LOCAL_DATE)
            .appendLiteral(' ')
            .append(DateTimeFormatter.ISO_LOCAL_TIME)
            .toFormatter();

Что мы получаем для дополнительных строк кода, так это (1) большее повторное использование встроенных средств форматирования (2) это средство форматирования будет принимать время без секунд и время с долей секунды, потому что DateTimeFormatter.ISO_LOCAL_TIME делает.

Ссылка на сайт

Статья в Википедии: ISO 8601

Только что узнал, что это тоже вариант для разбора:)

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "uuuu-MM-dd HH:mm:ss")
private LocalDateTime dateOccurred;
Другие вопросы по тегам