Java Mysql服务器在操作系统时间之外节省了3个小时的LocalDateTime
在服务将LocaDateTime写入数据库的过程中,在我的例子中,在使用java 8的spring boot API中,当在数据库端保存配置为时间戳的属性并在API中保存LocaDateTime时,该日期将在当前操作系统日期之后的3小时内保存 假设我试着在早上10点做这件事,保存到数据库的日期应该是11小时,但在我的情况下,它不是这样工作的Java Mysql服务器在操作系统时间之外节省了3个小时的LocalDateTime,java,mysql,spring-boot,spring-data-jpa,Java,Mysql,Spring Boot,Spring Data Jpa,在服务将LocaDateTime写入数据库的过程中,在我的例子中,在使用java 8的spring boot API中,当在数据库端保存配置为时间戳的属性并在API中保存LocaDateTime时,该日期将在当前操作系统日期之后的3小时内保存 假设我试着在早上10点做这件事,保存到数据库的日期应该是11小时,但在我的情况下,它不是这样工作的 private LocalDateTime dataLimite; @PrePersist public void prepareToSave() {
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();
结果就是操作系统的日期和时间,那么发生的真正问题是什么呢?如何解决此问题?LocalDateTime
仔细阅读文档
此类不存储或表示时区。相反,它是对日期的描述,用于生日,与挂钟上显示的当地时间相结合。如果没有诸如偏移量或时区之类的附加信息,它不能表示时间线上的某个瞬间
Java中的LocalDateTime类不能用于表示时刻。它代表了大约26-27小时范围内的潜在时刻,即全球时区的范围
此类包含日期和时间,但故意缺少时区或UTC偏移量的概念。因此,如果你存储,例如,今年1月23日的中午,我们不知道你是指东京、加尔各答、巴黎还是蒙特勒尔的中午……所有不同的时刻,几个小时的间隔,发生在东部的较早时间和西部的较晚时间
所以你使用了错误的类。暂时使用Instant、OffsetDateTime或ZonedDateTime
时间戳
请仔细阅读文档
MySQL 8中的时间戳类型类似于带时区的SQL标准类型时间戳。这种类型表示一个时刻,时间线上的一个特定点
将提交到数据库的文档调整为UTC进行存储
MySQL将时间戳值从当前时区转换为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 ) ;