首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Spring中用JVM MySql动态设置-Duser.timezone时区

在Spring中用JVM MySql动态设置-Duser.timezone时区
EN

Stack Overflow用户
提问于 2020-04-15 17:02:35
回答 1查看 619关注 0票数 0

我在"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中添加了美国/洛杉矶“。一切如期而至。

问题:

  1. 是否有任何方法可以使MySQL TZ与spring引导Java应用程序TZ对齐,即通过从参数中选择值来动态传递"-Duser.timezone“arg?
  2. 在MySQL DB中,我可以检查每个连接的时区吗?类似于in,我可以从“显示处理列表”查询中看到连接列表。
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-15 23:59:36

tl;dr

使用java.time类可以避免时区问题。

代码语言:javascript
复制
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

代码语言:javascript
复制
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 (可选的InstantZonedDateTime)。

代码语言:javascript
复制
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意味着这种数据类型不能表示某个时刻,而不是时间线上的一个点。

代码语言:javascript
复制
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.DateCalendarSimpleDateFormat

要了解更多信息,请参见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类?

  • Java 8Java 9Java 10Java 11和更高版本--捆绑实现的标准Java的一部分。
    • Java 9添加了一些次要的特性和修复。

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

https://stackoverflow.com/questions/61234440

复制
相关文章

相似问题

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