我在"IST“TZ中有一个Ubuntu 16服务器。
MySQL (v5.7)服务器在"IST“TZ中。
Spring (v2),Java (v1.8) jar在“America/”中。背景来自-Duser.timezone arg。
问题:由于我的Java obj位于“America/Los Angeles”中,获取MySQL数据不起作用,因为MySQL日期比java日期晚了一天。
在记录实际日期obj (使用查询参数obj )时,没有将其传递给查询,并在select *之后从MySQL获取Java对象。
解决方案:在"spring.jpa.properties.hibernate.jdbc.time_zone = application.properties中添加了美国/洛杉矶“。一切如期而至。
问题:
发布于 2020-04-15 23:59:36
tl;dr
使用java.time类可以避免时区问题。
ZoneId z = ZoneId.of( "America/Los_Angeles" ) ;
myPreparedStatament.setObject( … , java.time.OffsetDateTime.now( z ) ) ; // Persisting
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ; // Retrieval
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ; // Adjust into the wall-clock time used by the people of a particular region (a time zone). Same moment, same point on the timeline.java.time
我的Java日期表
Date类(java.util.Date & java.sql.Date)都是可怕的,现在是遗留的,多年前被JSR 310中定义的现代java.time类所取代。
我在"IST“TZ中有一个Ubuntu 16服务器。
FYI,服务器通常最好设置为UTC (GMT)的默认时区,偏移量为零小时-分钟-秒。请注意,主机OS有自己的默认时区,JVM有自己的默认时区。中间件(如与数据库的交互会话)可能有自己的当前默认时区。
作为一个Java程序员,您永远不应该依赖当前的默认时区。JVM中任何应用程序线程中的任何代码都可以在运行时随时更改默认值。因此,最好指定预期/期望的时区。
"spring.jpa.properties.hibernate.jdbc.time_zone =美国/洛杉矶“
如果您与数据库交换java.time类,而不是使用字符串或遗留日期时间类,则不需要此设置。Hibernate的最新版本JDBC 4.2和JPA 2.2都需要对java.time对象的支持。
是否有任何方法可以使MySQL TZ与spring引导Java应用程序TZ对齐,即通过从参数中选择值来动态传递"-Duser.timezone“arg?
如果您将java.time对象与数据库交换,这个问题就会变得毫无意义,问题就会消失,您的生活也会变得更容易。
在MySQL DB中,我可以检查每个连接的时区吗?类似于in,我可以从“显示处理列表”查询中看到连接列表。
同样,使用java.time对象,这个问题就没有意义了。
示例代码
仅限日期,无日时,无时区
对于类似于SQL标准DATE的列类型,请使用java.time.LocalDate。
ZoneId z = ZoneId.of( "Africa/Casablanca" ) ;
myPreparedStatament.setObject( … , LocalDate.now( z ) ) ; // Persisting
LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ; // Retrieval瞬间,时间线上的一个点
对于类似于SQL标准TIMESTAMP WITH TIME ZONE的列类型,请使用java.time.OffsetDateTime (可选的Instant或ZonedDateTime)。
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
myPreparedStatament.setObject( … , java.time.OffsetDateTime.now( z ) ) ; // Persisting
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ; // Retrieval不是一刻,只是日期和时间。
对于类似于SQL标准TIMESTAMP WITHOUT TIME ZONE的列类型,请使用java.time.LocalDateTime。请注意:缺少时区的任何概念或偏离-UTC意味着这种数据类型不能表示某个时刻,而不是时间线上的一个点。
myPreparedStatament.setObject( … , LocalDateTime.of( 2020 , Month.MAY , 15 , 22 , 0 , 0 , 0 ) ; // Persisting
LocalDateTime let = myResultSet.getObject( … , LocalDateTime.class ) ; // Retrieval

关于java.time
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/package-summary.html框架内置到Java8和更高版本中。这些类取代了麻烦的旧遗赠日期时间类,如java.util.Date、Calendar和SimpleDateFormat。
要了解更多信息,请参见http://docs.oracle.com/javase/tutorial/datetime/TOC.html。并搜索堆栈溢出以获得许多示例和解释。规范是JSR 310。
http://www.joda.org/joda-time/项目现在在维护模式中,建议迁移到java.time类。
您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC 4.2。不需要字符串,也不需要java.sql.*类。
在哪里获得java.time类?
https://stackoverflow.com/questions/61234440
复制相似问题