You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将带UTC偏移量的时间戳反序列化为java.time.Instant

如何将带UTC偏移量的时间戳反序列化为java.time.Instant

你遇到的问题是Jackson默认的JavaTimeModule无法解析2023-05-04T19:40:07.000+0200这种格式的时间字符串到Instant——原因是该格式的偏移部分(+0200)不带冒号,不符合Instant默认支持的ISO-8601标准格式(标准偏移格式为+02:00)。下面提供几种可行的解决方案:

方案一:用@JsonFormat注解指定自定义格式

直接在实体类的Instant字段上添加注解,明确匹配目标字符串的格式:

import com.fasterxml.jackson.annotation.JsonFormat;
import java.time.Instant;

static class MyClass {
    // 省略构造方法、getter、setter

    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = "UTC")
    private Instant time;
}

这里的pattern中,Z对应不带冒号的UTC偏移格式(如+0200),timezone确保最终转换为UTC时区的Instant。

方案二:给ObjectMapper配置自定义反序列化器

如果不想修改实体类,可以通过给ObjectMapper添加自定义反序列化器来适配格式:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.junit.jupiter.api.Test;

import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;

public class MyInstantTest {

    @Test
    void test1() throws JsonProcessingException {
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        // 添加自定义Instant反序列化器
        javaTimeModule.addDeserializer(Instant.class, new StdDeserializer<Instant>(Instant.class) {
            @Override
            public Instant deserialize(com.fasterxml.jackson.core.JsonParser p, com.fasterxml.jackson.databind.DeserializationContext ctxt) throws java.io.IOException {
                String timeStr = p.getText();
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
                OffsetDateTime offsetDateTime = OffsetDateTime.parse(timeStr, formatter);
                return offsetDateTime.toInstant();
            }
        });

        final ObjectMapper objectMapper = new ObjectMapper()
                .registerModule(javaTimeModule)
                .disable(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
                .disable(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS);

        final MyClass deserializedObject = objectMapper.readValue("{\"time\":\"2023-05-04T19:40:07.000+0200\"}", MyClass.class);
        System.out.println("deserializedObject.getTime() = " + deserializedObject.getTime());
    }

    static class MyClass {
        // 原实体类代码不变
        MyClass() {}
        MyClass(Instant time) { this.time = time; }
        public Instant getTime() { return time; }
        public void setTime(final Instant time) { this.time = time; }
        private Instant time;
    }
}

逻辑是先把字符串解析为支持带偏移格式的OffsetDateTime,再转换为Instant。

方案三:临时用OffsetDateTime中转

如果允许修改实体类字段类型,可以先将字段定义为OffsetDateTime,在getter中转换为Instant:

import java.time.Instant;
import java.time.OffsetDateTime;

static class MyClass {
    private OffsetDateTime time;

    // 构造方法调整
    MyClass() {}
    MyClass(Instant time) { this.time = OffsetDateTime.ofInstant(time, java.time.ZoneOffset.UTC); }

    public Instant getTime() {
        return time.toInstant();
    }

    public void setTime(final OffsetDateTime time) {
        this.time = time;
    }
}

这种方式无需额外配置Jackson,因为JavaTimeModule默认支持OffsetDateTime解析(包括+0200格式)。

内容的提问来源于stack exchange,提问作者Saif

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 08:19:55