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

Spring REST API中Timestamp字段返回值自动减2小时求助

解决Spring REST API中Timestamp返回时区偏移问题

这个问题我之前也碰到过,本质是时区和Jackson序列化规则导致的,咱们一步步拆解解决:

问题根源

你看到的2019-09-03T22:00:00Z是UTC时区的ISO 8601格式(Z代表UTC),而你预期的2019-09-04 00:00:00.000是UTC+2时区的本地时间格式。Java的Timestamp本身存储的是UTC时间戳,不带时区信息,Spring默认用Jackson序列化时,会把它转成UTC的标准格式,所以看起来像是少了2小时,其实是时区转换的显示问题,不是时间值本身错误。修改电脑系统时间没用,因为Java程序的时区配置(或Jackson的序列化规则)才是决定显示的关键。

解决方案

方案1:全局配置Jackson的时区和日期格式

如果希望所有接口的日期类型都按统一格式返回,可以在Spring中添加全局Jackson配置:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.text.SimpleDateFormat;
import java.util.TimeZone;

@Configuration
public class JacksonGlobalConfig {
    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        // 设置你需要的时区(这里是UTC+2,对应你差2小时的场景)
        mapper.setTimeZone(TimeZone.getTimeZone("GMT+2"));
        // 指定日期序列化格式,和你的预期格式一致
        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"));
        // 注册Java 8时间模块(如果用JDK8+的时间类型,比如LocalDateTime,这个很必要;用Timestamp也可以加上)
        mapper.registerModule(new JavaTimeModule());
        // 关闭默认的日期转时间戳功能
        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        return mapper;
    }
}

方案2:单独给DTO字段加注解配置

如果只想针对ActionCustomDto的日期字段修改格式,直接在字段上用Jackson的@JsonFormat注解:

import com.fasterxml.jackson.annotation.JsonFormat;
import java.sql.Timestamp;

public class ActionCustomDto {
    private String actionDescription;
    
    // 指定格式、时区,强制转成字符串输出
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss.SSS", timezone = "GMT+2")
    private Timestamp startDate;
    
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss.SSS", timezone = "GMT+2")
    private Timestamp dueDate;
    
    // 其他字段和对应的getter/setter...
}

方案3:检查数据库连接的时区配置

还要确认数据库存储和读取时的时区是否正确,比如MySQL的话,可以在JDBC URL里明确指定时区,避免驱动自动转换:

jdbc:mysql://your-db-host:3306/your-db-name?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B2&useLegacyDatetimeCode=false

验证效果

配置完成后,重启服务再调用接口,就能得到你预期的2019-09-04 00:00:00.000格式的日期了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:03:02