【问题标题】:OffsetDateTime value is changed when retrieved from the database从数据库中检索时,OffsetDateTime 值已更改
【发布时间】:2021-09-19 18:27:03
【问题描述】:

我正在使用MS SQL 数据库中的一个表,并使用Spring Boot 开发了一个GET API,以从该表中检索所有数据。
这里的表包含datetimeoffset(7) 类型的列。

我的实体中有数据成员OffsetDateTime updatedDate,用于映射数据库中的datetimeoffset

现在,当我收到 API 响应时,我看到 updatedDate 值 (2021-06-17T05:37:40.1938687+05:30) 与实际数据库值 (2021-06-16 19:07:40.1938687 -05:00).

我在网上寻找一些帮助并尝试了一些类似于Solution 的解决方案,但是我没有看到任何积极的结果。

任何帮助都将非常感激,谢谢!

附言。 Spring Boot版本:2.3.1.RELEASE

【问题讨论】:

    标签: java spring-boot jackson timezone offsetdatetime


    【解决方案1】:

    这两个值代表时间轴上完全相同的点。它们只是用不同的时区表示:数据库使用ESTSpring 应用使用IST Indian。当我们将它们转换为 GMT 时,它们看起来会一样:

    String[] dates = {"2021-06-17T05:37:40.1938687 +05:30", "2021-06-16T19:07:40.1938687 -05:00"};
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.n XXX")
            .withZone(ZoneId.of("GMT"));
    Arrays.stream(dates)
            .map(date -> formatter.format(OffsetDateTime.parse(date, formatter)))
            .forEach(System.out::println);
    

    上面的代码打印:

    2021-06-17T00:07:40.1938687 Z
    2021-06-17T00:07:40.1938687 Z
    

    如果您想保留原始表示,您需要指示使用EST 时区而不是默认或系统时区。尝试在配置文件中设置:spring.jackson.time-zone属性:

    格式化日期时使用的时区。例如, “美国/洛杉矶”或“GMT+10”。

    【讨论】:

    • 感谢您的回复。我在 application.properties 中添加了 spring.jackson.time-zone 属性,值为 GMT-5,但是我仍然看到相同的结果。除了帖子stackoverflow.com/questions/46653455/…,我还需要做任何其他与杰克逊相关的配置吗
    • @Vishal,您使用哪个版本的Jackson?您是创建自己的ObjectMapper 实例还是使用Spring 创建的普通实例?当您创建一个测试控制器并返回OffsetDateTime 的新实例时,它是如何工作的?
    • 我使用Jackson 版本作为2.11.0 是的,我提供了ObjectMapper 的自定义实例,其中我明确禁用WRITE_DATES_AS_TIMESTAMPSADJUST_DATES_TO_CONTEXT_TIME_ZONE 当我返回@987654338 的新实例时@,我看到它有 IST 区域
    • 嗨 Michal,顺便说一句,当我发送具有不同 ZoneOffset 的 OffsetDateTime 实例时,我在 API 响应中正确看到了新区域。例如,OffsetDateTime now = OffsetDateTime.now(); now = now.withOffsetSameInstant(ZoneOddset.of("-05:30"); return now; 我需要 jackson 为我做这件事。
    • @Vishal,同时尝试检查OffsetDateTime 从数据库加载时的样子。您使用Hibernate 或任何其他ORM?看看Hibernate not correctly storing ZonedDateTime as datetimeoffset in SQL Server
    【解决方案2】:

    现在,当我收到 API 响应时,我看到了 updatedDate 值 (2021-06-17T05:37:40.1938687+05:30) 与实际数据库不同 值(2021-06-16 19:07:40.1938687 -05:00)。

    不,两个日期时间都代表相同的瞬间/时刻。

    演示:

    import java.time.Instant;
    
    public class Main {
        public static void main(String[] args) {
            System.out.println(Instant.parse("2021-06-17T05:37:40.1938687+05:30"));
            System.out.println(Instant.parse("2021-06-16T19:07:40.1938687-05:00"));
        }
    }
    

    输出:

    2021-06-17T00:07:40.193868700Z
    2021-06-17T00:07:40.193868700Z
    

    ONLINE DEMO

    您可以将一个转换成另一个

    使用OffsetDateTime#withOffsetSameInstant,您可以将一个转换为另一个。

    演示:

    import java.time.OffsetDateTime;
    import java.time.ZoneOffset;
    
    public class Main {
        public static void main(String[] args) {
            OffsetDateTime odtFromResponse = OffsetDateTime.parse("2021-06-17T05:37:40.1938687+05:30");
    
            OffsetDateTime odtDesired = odtFromResponse.withOffsetSameInstant(ZoneOffset.of("-05:00"));
            System.out.println(odtDesired);
        }
    }
    

    输出:

    2021-06-16T19:07:40.193868700-05:00
    

    ONLINE DEMO

    Trail: Date Time 了解有关现代日期时间 API 的更多信息。

    【讨论】:

    • 是的,我可以理解日期完全相同,只是时区不同。我不希望杰克逊将日期从 EST 转换为 IST,为此我设置了配置(在stackoverflow.com/questions/46653455/… 帖子中提到)。但是我仍然看到检索到的日期包含 IST 时区,而不是 EST
    • @Vishal - 试试@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="uuuu-MM-dd'T'HH:mm:ss.SSSSSSSSSXXX", timezone="America/Chicago") OffsetDateTime updatedDate,如果它解决了您的问题,请告诉我。根据您的数据库服务器的时区更改时区。
    • 嗨,Arvind,在进行建议的更改后,我仍然看到相同的时区。我是否需要停止提供 ObjectMapper 的自定义实现? JFYI,OffsetDateTime 成员在 @Entity 内部,我使用了 @JsonFormat 注释。
    • @Vishal - 从您的其他评论中,我注意到您已经实现了自定义 ObjectMapper。你有没有尝试过this comment中的建议?
    • 嗨,Arvind,我已经尝试过了,但没有运气。我的问题的一种解决方案是,使 JVM 时区和 DB 时区相同,例如,使用 JVM 参数-Duser.timezone=US/Central。这有助于解决这个问题。但是,就我而言,我不想让 Spring Boot 应用程序依赖于数据库的时区。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-21
    • 2018-05-24
    • 2023-03-24
    • 2016-01-04
    相关资源
    最近更新 更多