Распарсить OffsetDateTime из String

От сервиса приходит json с полем "time": "2020-05-28T12:34:56", которое должно далее обрабатываться как OffsetDateTime.

Я пробовал такими методами, но падают ошибки:

String date = "2020-05-28T12:34:56";
OffsetDateTime offsetDateTime = OffsetDateTime.parse(date, DateTimeFormatter.ISO_DATE_TIME);
OffsetDateTime offsetDateTime = OffsetDateTime.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"));

Подскажите, пожалуйста.


Ответы (2 шт):

Автор решения: Andrew Bystrov

Вы можете распарсить данную строку как LocalDateTime и потом уже перевести в OffesetDateTime примерно так

jshell> var date = "2020-05-28T12:34:56"; // нужная строка
date ==> "2020-05-28T12:34:56"

jshell> var localDateTime = java.time.LocalDateTime.parse(date); // переводим в LocalDateTime
localDateTime ==> 2020-05-28T12:34:56

jshell>var offsetDateTime localDateTime.atOffset(java.time.ZoneOffset.ofHours(0)); // переводит в OffsetDateTime
offsetDateTime ==> 2020-05-28T12:34:56Z
→ Ссылка
Автор решения: Alexandr

Можно использовать кастомный Deserializer

package com.somepackage;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import lombok.Data;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class OffsetDateTimeTest {

    @Data
    static class SomeClass {

        @JsonProperty("time")
        @JsonDeserialize(using = CustomDeserializer.class)
        private OffsetDateTime time;
    }

    public static class CustomDeserializer extends JsonDeserializer<OffsetDateTime> {

        private final DateTimeFormatter formatter;

        public CustomDeserializer() {
            this.formatter =
                    DateTimeFormatter.ofPattern(
                            "yyyy-MM-dd'T'HH:mm:ss");
        }

        public CustomDeserializer(
                DateTimeFormatter formatter) {
            this.formatter = formatter;
        }

        @Override
        public OffsetDateTime deserialize(
                JsonParser parser,
                DeserializationContext context) throws IOException, JsonProcessingException {
            LocalDateTime ldt =
                    LocalDateTime.parse(parser.getText(), formatter);
            ZoneId z = ZoneId.systemDefault();
            ZoneOffset zo = z.getRules().getOffset(ldt);
            return ldt.atOffset(zo);
        }
    }

    @Test
    public void testDeserialization() {
        assertDoesNotThrow(
                () -> {
                    String json = "{\"time\": \"2020-05-28T12:34:56\"}";
                    ObjectMapper mapper = new ObjectMapper();
                    SomeClass someClass =
                            mapper.readValue(json, SomeClass.class);
                    assertEquals(someClass.getTime().toString(), "2020-05-28T12:34:56+06:00");
                });
    }

}
→ Ссылка