首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >关于mysql时间戳字段的一些问题

关于mysql时间戳字段的一些问题
EN

Stack Overflow用户
提问于 2021-11-09 16:59:56
回答 2查看 35关注 0票数 0

我尝试插入一条记录。当服务器的时区大于数据库设置的时区时,我发现了一个问题。时间戳将自动转换该字段中的数据。如图所示,我在11-10 00:51 As插入此记录,服务器时区为+8

enter image description here

但反过来,当服务器的时区小于数据库设置的时区时,它不会进行转换

我在11-09 21:56 is插入此记录,服务器时区为+5

enter image description here

我使用java进行测试,orm框架是jpa,我使用jdbc连接mysql。

有人能告诉我为什么吗?

EN

回答 2

Stack Overflow用户

发布于 2021-11-09 21:33:29

tl;dr

代码语言:javascript
运行
复制
myPreparedStatement.setObject( 
    … , 
    ZonedDateTime
    .of( 
        LocalDate.of( 2021 , Month.NOVEMBER , 10 ) , 
        LocalTime.of( 0 , 51 ) , 
        ZoneId.of( "Australia/Perth" ) 
    )                                                  // Returns a `ZonedDateTime` object.
    .toOffsetDateTime()                                // Returns a `OffsetDateTime` object.
)

…和…

代码语言:javascript
运行
复制
myResultSet.getObject( 
    … , 
    OffsetDateTime.class 
)                                                      // Returns a `OffsetDateTime` object.
.atZoneSameInstant( 
    ZoneId.of( "Australia/Perth" ) 
)                                                      // Returns a `ZonedDateTime` object.

详细信息

不要相信您的工具会报告检索到的真值。某些工具具有在从数据库检索日期-时间值后应用时区的反功能。用意是好的,但却非常令人困惑。

MySQL 8中的TIMESTAMP列始终存储调整为协调世界时的值。这意味着在UTC子午线之前或之后零小时-分钟-秒的偏移量。每个the docs

MySQL将时间戳值从当前时区转换为协调时区进行存储,并从协调时区转换回当前时区以进行检索。

Always 指定所需的 或offset-from-UTC。不要在Java、数据库连接或数据库服务器中隐式依赖默认时区。

代码语言:javascript
运行
复制
ZoneId z = ZoneId.of( "Asia/Hong_Kong" ) ;

始终使用java.time类。切勿使用旧的Date**Calendar,** SimpleDateFormat类。

代码语言:javascript
运行
复制
LocalDate ld = LocalDate.of( 2021 , Month.NOVEMBER , 10 ) ;
LocalTime lt = LocalTime.of( 0 , 51 ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;

要发送到数据库,请通过OffsetDateTime类将时区转换为纯粹的偏移量,以与SQL兼容。

代码语言:javascript
运行
复制
OffsetDateTime odt = zdt.toOffsetDateTime() ;

如果要查看最终将存储在数据库中的值,请将偏移量调整为零。

代码语言:javascript
运行
复制
OffsetDateTime odt = zdt.toOffsetDateTime().withOffsetSameInstant( ZoneOffset.UTC ) ;

发送到数据库。

代码语言:javascript
运行
复制
myPreparedStatement.setObject( … , odt ) ;

从数据库中检索。

代码语言:javascript
运行
复制
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;

调整为时区。

代码语言:javascript
运行
复制
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;  // Same moment but viewed through the wall-clock time of a particular time zone.

您提到使用JPA (现在称为)。JPA的最新版本完全支持java.time类。提示:要试验和了解这一切是如何工作的,请跳过JPA并进行一些直接的JDBC调用作为练习。

所有这些都已经在Stack Overflow上被多次介绍过了。搜索以了解更多信息。

票数 1
EN

Stack Overflow用户

发布于 2021-11-09 17:04:42

您的MySQL服务器上的time_zone参数如何?您可以使用以下查询进行检查:

SELECT @@time_zone

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69902146

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档