使用分区时间将字符串转换为LocalDateTime

发布于 2025-01-26 13:45:02 字数 1357 浏览 4 评论 0原文

我收到了一个带有日期和偏移的主题中的字符串字段,我需要通过添加偏移来将此字符串转换为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

如何我实现了这个目标?

I received a String field in a topic with date and offset and I need to convert this String to a LocalDateTime by adding the offset. For example, if I received:

2021-07-20T19:00:00.000+02:00

I want to convert in LocalDateTime:

2021-07-20T21:00:00.000

And I have a Bean with custom object mapper for this purpose:

@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);
    }

}

But it doesn't work as I expect, since the resulting LocalDateTime offset disappears and is not added:

2021-07-20T19:00:00.000

How can I achieve this goal?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

最美不过初阳 2025-02-02 13:45:02

LocalDateTime类是一个日期时间表示,它不知道时区,并且唯一合乎逻辑的是,localDateTeTimedEserialializer忽略了源数据中的任何时区信息。

要考虑时区域,您可以使用instantDeserializer.offset_date_time deserializer(dateTimeFormatter.iso_offset_date_date_time实际上是您拥有的源日期的格式),并将其结果转换为结果LocalDateTime在所需区域内。可以将其包裹在自定义的避难器中,以易于使用,例如

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());

The LocalDateTime class is a date-time representation which is unaware of time zones and it's only logical that the LocalDateTimeDeserializer ignores any time zone information in the source data.

To account for the time zone you could use the InstantDeserializer.OFFSET_DATE_TIME deserializer (DateTimeFormatter.ISO_OFFSET_DATE_TIME is actually the format of the source date time you have) and have its result converted to LocalDateTime within a desired zone. This can be wrapped in a custom deserializer for ease of use, e.g.

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());
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文