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

REST响应的Date属性能否直接转为LocalDateTime或LocalDate?

问题:直接将时间戳反序列化为LocalDateTime的可行性及解决方案

类结构与返回数据

本地应用类

public class MyLocalApplicationClass {
    private String name;
    private LocalDateTime creationDate;
    private String createdBy;
}

远程REST服务对应类结构

public class MyRemoteApplicationClass {
    private String name;
    private Date creationDate;
    private String createdBy;
}

实际返回的JSON示例

{
    "name": "anything",
    "creation_date": 1666190973000,
    "created_by": "anyone"
}

核心疑问

能否直接将上述时间戳接收为LocalDateTime类型,还是必须先接收为Date再转为LocalDateTime?

尝试过程及错误信息

尝试直接反序列化为LocalDateTime

抛出错误:

raw timestamp (1656015404000) not allowed for 
java.time.LocalDateTime: need additional information such as an
offset or time-zone (see class Javadocs)

翻译:

原始时间戳(1656015404000)无法反序列化为java.time.LocalDateTime:需要额外信息,例如偏移量或时区(详见类文档)

尝试反序列化为LocalDate

已添加jsr310依赖,并使用注解@JsonSerialize(using = LocalDateSerializer.class) @JsonDeserialize(using = LocalDateDeserializer.class),仍抛出如下错误及警告:

Java 8 date/time type `java.time.DateTimeException` not supported
by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310"
to enable handling (through reference chain:
com.fasterxml.jackson.databind.JsonMappingException["cause"])

WARN -- com.fasterxml.jackson.databind.JsonMappingException:
Invalid value for EpochDay (valid values -365243219162 - 365241780471): 1656015404000

翻译:

默认不支持Java 8日期/时间类型java.time.DateTimeException:请添加模块com.fasterxml.jackson.datatype:jackson-datatype-jsr310以启用处理(引用链:com.fasterxml.jackson.databind.JsonMappingException["cause"])

警告 -- com.fasterxml.jackson.databind.JsonMappingException: EpochDay值无效(有效值范围为 -365243219162 至 365241780471):1656015404000

解决方案

可以直接将时间戳反序列化为LocalDateTime,无需先转换为Date。报错的核心原因是LocalDateTime本身不包含时区信息,而时间戳是基于UTC的绝对时间,必须指定时区/偏移量才能完成转换。具体实现如下:

1. 确认依赖配置

确保项目中已引入Jackson的JSR310模块(以Maven为例):

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>你的Jackson版本号</version>
</dependency>

2. 配置反序列化规则

有两种常用方式:

方式一:全局配置(推荐)

在ObjectMapper中全局注册JSR310模块,并指定默认时区,让所有时间戳反序列化时使用该时区转换为LocalDateTime:

ObjectMapper objectMapper = new ObjectMapper();
// 注册Java 8日期时间模块
objectMapper.registerModule(new JavaTimeModule());
// 设置默认时区,可根据需求选择UTC或系统时区
objectMapper.setTimeZone(TimeZone.getTimeZone("UTC"));
// 允许将日期调整为上下文时区
objectMapper.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, true);

方式二:字段级注解

在LocalDateTime字段上添加注解,明确指定反序列化时的时区:

public class MyLocalApplicationClass {
    private String name;
    
    @JsonFormat(shape = JsonFormat.Shape.NUMBER, timezone = "UTC")
    private LocalDateTime creationDate;
    
    private String createdBy;
}

或者自定义反序列化器,手动将时间戳转换为LocalDateTime:

public class TimestampToLocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
    @Override
    public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        long timestamp = p.getLongValue();
        // 这里可替换为业务需要的时区,比如ZoneId.systemDefault()
        return Instant.ofEpochMilli(timestamp)
                      .atZone(ZoneId.of("UTC"))
                      .toLocalDateTime();
    }
}

然后在字段上引用该反序列化器:

@JsonDeserialize(using = TimestampToLocalDateTimeDeserializer.class)
private LocalDateTime creationDate;

关于LocalDate尝试失败的说明

报错的原因是LocalDateDeserializer默认将数字解析为自纪元以来的天数,而传入的是毫秒级时间戳,数值远超出EpochDay的有效范围。如果需要将时间戳转为LocalDate,同样需要自定义反序列化逻辑,先将时间戳转为Instant,再指定时区转换为LocalDate。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 14:55:23