在服务将时间戳写入数据库的过程中,在我的例子中,在使用java8的spring boot API中,当保存数据库端配置为LocaDateTime的属性和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();结果就是操作系统的日期和时间,那么真正发生的问题是什么呢?如何解决此问题?
发布于 2019-05-05 08:33:28
LocalDateTime
更仔细地阅读文档。
此类不存储或表示时区。相反,它是一种日期的描述,用于生日,与挂钟上看到的当地时间相结合。如果没有诸如偏移量或时区之类的附加信息,它就不能表示时间线上的瞬间。
Java中的LocalDateTime类不能用来表示瞬间。它代表了大约26-27小时范围内的潜在时刻,也就是全球各地的时区范围。
此类包含日期和时间,但故意缺少任何时区或与UTC的偏移量概念。例如,如果您存储的是今年1月23日的中午,我们不知道您是指东京、加尔各答、巴黎还是Montréal…。所有不同的时刻,相隔几个小时,在东方发生得更早,在西方发生得更晚。
因此,您使用了错误的类。暂时可以使用Instant、OffsetDateTime或ZonedDateTime。
TIMESTAMP
更仔细地阅读文档。
SQL8中的TIMESTAMP类型类似于MySQL标准类型TIMESTAMP WITH TIME ZONE。此类型表示时间线上的某个时刻。
将片刻提交给数据库的文档explains调整为UTC进行存储。
MySQL将
TIMESTAMP值从当前时区转换为协调时区进行存储,然后从协调时区转换回当前时区以进行检索。
这就解释了你的问题。您隐含地依赖于将当前默认时区分配给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 ) ;

https://stackoverflow.com/questions/55984115
复制相似问题