【问题标题】:Mysql server saves LocalDateTime with 3 hours beyond OS timeMysql 服务器将 LocalDateTime 保存为超出操作系统时间 3 小时
【发布时间】:2019-05-04 15:36:07
【问题描述】:

在服务将 LocaDateTime 写入数据库的过程中,在我的例子中,在使用 java 8 的 Spring Boot API 中,当在数据库端保存配置为 TIMESTAMP 的属性和 API 中的 LocaDateTime 时,该日期正在保存超过当前操作系统日期 3 小时。

假设我尝试在早上 10 点准确执行此操作,保存到数据库的日期应该是 11 小时,但在我的情况下它不是这样工作的......

private LocalDateTime dataLimite;

@PrePersist
public void prepareToSave() {
    String str = "1986-04-08 10:00";
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
    LocalDateTime dateTime = LocalDateTime.parse(str, formatter);
    this.dataLimite = dateTime.plusHours(1);
}

显然可能会注意到这是Mysql配置方面的问题,但是当我测试时......

SELECT NOW();

结果正是操作系统的日期和时间,那么真正发生的问题是什么?如何解决这个问题?

【问题讨论】:

  • 所有软件/服务器是否在同一个时区?
  • 是的,我在保存日期之前调试了应用程序,一切都与它应该的完全一样。
  • Markdown 标记中的> 用于引用,而不是您自己的散文。我修正了你的格式。

标签: java mysql spring-boot spring-data-jpa


【解决方案1】:

LocalDateTime

更仔细地阅读文档。

此类不存储或表示时区。相反,它是对日期的描述,用于生日,结合挂钟上的当地时间。如果没有偏移或时区等附加信息,它不能代表时间线上的瞬间。

Java 中的LocalDateTime 类不能用于表示时刻。它代表大约 26-27 小时范围内的潜在时刻,即全球时区范围。

此类包含日期和时间,但故意缺少任何时区或与 UTC 偏移的概念。因此,如果您存储,例如,今年 1 月 23 日中午,我们不知道您指的是东京、加尔各答、巴黎还是蒙特利尔的中午……所有不同的时刻,相隔数小时,发生在东部早些时候和之后西部。

所以你使用了错误的类。暂时使用InstantOffsetDateTimeZonedDateTime

TIMESTAMP

更仔细地阅读文档。

MySQL 8 中的 TIMESTAMP 类型类似于 SQL 标准类型 TIMESTAMP WITH TIME ZONE。这种类型代表一个时刻,时间线上的一个特定点。

文档explains 将提交到数据库的时刻调整为UTC进行存储。

MySQL 将TIMESTAMP 值从当前时区转换为 UTC 进行存储,并从 UTC 转换回当前时区进行检索。

这解释了您的问题。您隐含地依赖当前默认时区分配给 Java 中缺少任何时区的错误类型的对象。 切勿编写依赖于服务器当前默认时区(或区域设置)的代码,因为这超出了程序员的控制范围。相反,始终明确指定您想要/预期的时区。或者更好的是,只要有可能就在 UTC 工作。

为了获得最佳结果,在与数据库交换值时坚持使用 UTC。

OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;

myPreparedStatement.setObject( … , odt ) ;

检索。

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;

要通过特定地区的人们使用的挂钟时间查看那一刻,请申请ZoneId 以获取ZonedDateTime

ZoneId z = ZoneId.of( "Australia/Sydney" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-16
    • 1970-01-01
    • 2010-09-18
    相关资源
    最近更新 更多