MySQL是在时区"GMT+8"下运行的,而Tomcat则是在"GMT"下运行。当我将datetime保存到数据库中时,一切似乎都没问题,但是当我检查数据库中datetime的值时,我看到了"GMT"的值。
另外,当我尝试从数据库获取值时,该值被更改,似乎数据库中的值被视为"GMT+8",因此Java将其更改为"GMT"。
我已经像这样设置了连接URL:
useTimezone=true&serverTimezone=GMT
但是它没有起作用。
MySQL是在时区"GMT+8"下运行的,而Tomcat则是在"GMT"下运行。当我将datetime保存到数据库中时,一切似乎都没问题,但是当我检查数据库中datetime的值时,我看到了"GMT"的值。
另外,当我尝试从数据库获取值时,该值被更改,似乎数据库中的值被视为"GMT+8",因此Java将其更改为"GMT"。
我已经像这样设置了连接URL:
useTimezone=true&serverTimezone=GMT
但是它没有起作用。
useTimezone是一种较旧的解决方法。MySQL团队最近重写了setTimestamp/getTimestamp代码,但只有在设置连接参数useLegacyDatetimeCode=false并且使用最新版本的mysql JDBC连接器时才会启用该功能。例如:
String url =
"jdbc:mysql://localhost/mydb?useLegacyDatetimeCode=false
如果你下载mysql-connector的源代码并查看setTimestamp方法,你会很容易地看到发生了什么:
如果使用旧日期时间代码= false,则调用newSetTimestampInternal(...)。然后,如果传递给newSetTimestampInternal的日历为NULL,则会在数据库的时区中格式化你的日期对象:
this.tsdf = new SimpleDateFormat("''yyyy-MM-dd HH:mm:ss", Locale.US);
this.tsdf.setTimeZone(this.connection.getServerTimezoneTZ());
timestampString = this.tsdf.format(x);
Calendar对象非常重要,因此请确保它为空 - 请确保使用:
setTimestamp(int,Timestamp).
不要使用setTimestamp(int,Timestamp,Calendar)方法。
现在应该很明显这是如何工作的了。如果你使用java.util.Calendar构造一个日期(例如:2011年1月5日早上3点),并设置为America/Los_Angeles时区(或任何你想要的时区),然后调用setTimestamp(1, myDate),它将采用SimpleDateFormat将你的日期按照数据库时区进行格式化。因此,如果你的数据库处于America/New_York时区,它将构造字符串“2011-01-05 6:00:00”以插入数据(因为纽约比洛杉矶快3个小时)。
要检索日期,请使用getTimestamp(int)(不需要Calendar参数)。再次,它将使用数据库时区来构建日期。
注意:现在Web服务器的时区完全无关紧要! 如果你不将useLegacyDatetimecode设置为false,则Web服务器时区将用于格式化 - 这会增加许多混乱。
注意:
可能MySQL会抱怨服务器时区是不明确的。例如,如果你的数据库设置为使用EST时区,在Java中可能有几种可能的EST时区,因此你可以通过告诉mysql-connector确切的数据库时区来澄清这一点:
String url =
"jdbc:mysql://localhost/mydb?useLegacyDatetimeCode=false&serverTimezone=America/New_York";
只有在它报错时你才需要这样做。
String url = "jdbc:mysql://localhost?tz=useLegacyDatetimeCode=false&serverTimezone=America/New_York";
。对于我的应用程序,这个示例链接有效:url: jdbc:mysql://localhost:3306/trip_planner?tz=useLegacyDatetimeCode=false&serverTimezone=Europe/Berlin
。 - mzoberJDBC使用所谓的“连接URL”,因此可以通过“%2B”来转义“+”符号,即
useTimezone=true&serverTimezone=GMT%2B8
GMT+1
(例如时区为“Europe/Vienna”)。IST
没有改变任何东西,而GMT+1
解决了问题。 - grinderX19更改数据库名称、用户名和密码
connection = DriverManager.getConnection("jdbc:mysql://localhost/databasename?user=username&password=userpassword"
+ "&userUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetime=false&serverTimezone=UTC");
对我来说没问题
spring.datasource.url= jdbc:mysql://localhost:3306/catalog?serverTimezone=UTC
有没有办法从MySQL获取支持的时区列表? 例如 - serverTimezone=America/New_York。这可以解决许多类似问题。我相信每次您需要指定正确的时区,无论是从应用程序还是数据库时区。