Я получил поле String в теме с датой и смещением, и мне нужно преобразовать эту строку в LocalDateTime, добавив смещение. Например, если я получил:
2021-07-20T19:00:00.000+02:00
Я хочу преобразовать в LocalDateTime:
2021-07-20T21:00:00.000
И у меня есть Bean с настраиваемым картографом объектов для этой цели:
@Configuration
public class MyConfiguration {
@Bean
public MyCustomObjectMapper configure() {
final ObjectMapper mapper = new ObjectMapper();
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX");
final LocalDateTimeDeserializer dateTimeDeserializer = new LocalDateTimeDeserializer(formatter);
final LocalDateTimeSerializer dateTimeSerializer = new LocalDateTimeSerializer(formatter);
final JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addDeserializer(LocalDateTime.class, dateTimeDeserializer);
javaTimeModule.addSerializer(LocalDateTime.class, dateTimeSerializer);
mapper.registerModule(javaTimeModule);
return new MyCustomObjectMapper (mapper);
}
}
Но это не работает, как я ожидаю, поскольку результирующее смещение LocalDateTime исчезает и не добавляется:
2021-07-20T19:00:00.000
Как я могу достичь этой цели?




Класс LocalDateTime представляет собой представление даты и времени, которое не знает о часовых поясах, и вполне логично, что LocalDateTimeDeserializer игнорирует любую информацию о часовом поясе в исходных данных.
Чтобы учесть часовой пояс, вы можете использовать десериализатор InstantDeserializer.OFFSET_DATE_TIME (на самом деле это формат исходной даты и времени, который у вас есть) и преобразовать его результат в DateTimeFormatter.ISO_OFFSET_DATE_TIME в нужной зоне. Это может быть обернуто в пользовательский десериализатор для простоты использования, например.
class SmartLocalDateTimeDeserializer extends StdDeserializer<LocalDateTime> {
private final InstantDeserializer<OffsetDateTime> delegate = InstantDeserializer.OFFSET_DATE_TIME;
public SmartLocalDateTimeDeserializer() {
super(LocalDateTime.class);
}
@Override
public LocalDateTime deserialize(JsonParser p,
DeserializationContext ctxt) throws IOException, JsonProcessingException {
final OffsetDateTime result = delegate.deserialize(p, ctxt);
return result.atZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime();
}
}
...
javaTimeModule.addDeserializer(LocalDateTime.class, new SmartLocalDateTimeDeserializer());
Можете ли вы добавить класс с полем
LocalDateTimeи включить любые аннотации, которые у вас есть в поле?