Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Java更改数据库连接中的MySQL时区?_Java_Mysql_Jdbc_Timezone - Fatal编程技术网

如何使用Java更改数据库连接中的MySQL时区?

如何使用Java更改数据库连接中的MySQL时区?,java,mysql,jdbc,timezone,Java,Mysql,Jdbc,Timezone,MySQL的时区为“GMT+8”,而Tomcat的时区为“GMT”。当我将datetime保存到数据库时,一切似乎都正常,但当我检查数据库中的datetime值时,我看到了“GMT”值 另外,当我尝试从数据库中获取值时,值被更改,似乎数据库中的值被视为“GMT+8”,所以Java将值更改为“GMT” 我已将连接URL设置为: useTimezone=true&serverTimezone=GMT 但是它不起作用。useTimezone是一种较老的解决方法。MySQL团队最近重写了set

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连接器源代码并查看setTimestamp,很容易看到发生了什么:

如果use legacy date time code=false,则调用newSetTimestampInternal(…)。然后,如果传递给newSetTimestampInternal的日历为空,则您的日期对象将在数据库的时区中格式化:

this.tsdf = new SimpleDateFormat("''yyyy-MM-dd HH:mm:ss", Locale.US);
this.tsdf.setTimeZone(this.connection.getServerTimezoneTZ());
timestampString = this.tsdf.format(x);
日历为空非常重要,因此请确保使用:

setTimestamp(int,Timestamp).
。。。不设置时间戳(int、Timestamp、Calendar)

现在应该很清楚这是怎么回事了。如果您使用java.util.Calendar和调用setTimestamp(1,myDate)在美国/洛杉矶(或任何您想要的时区)构建日期:2011年1月5日凌晨3:00,那么它将占用您的日期,使用SimpleDataFormat在数据库时区中格式化它。因此,如果您的DB位于美国/纽约,它将构造要插入的字符串“2011-01-05 6:00:00”(因为纽约比洛杉矶领先3小时)

要检索日期,请使用getTimestamp(int)(不带日历)。它将再次使用数据库时区来构建日期

注意:现在Web服务器时区完全不相关了如果不将useLegacyDatetimecode设置为false,则会使用Web服务器时区进行格式化,这会增加很多混乱


注:

我可能会抱怨服务器时区不明确。例如,如果您的数据库设置为使用EST,那么Java中可能有几个EST时区,因此您可以通过确切地告诉mysql connector数据库时区是什么来澄清这一点:

String url =
 "jdbc:mysql://localhost/mydb?useLegacyDatetimeCode=false&serverTimezone=America/New_York";
您只需要在它抱怨时执行此操作。

JDBC使用所谓的“连接URL”,因此您可以通过“%2B”转义“+”,即


对于Squirrel SQL Client()版本4等应用程序,您可以将“驱动程序属性”下的“serverTimezone”设置为
GMT+1
(时区“Europe/Vienna”的示例)。

有没有办法从MySQL获取支持的时区列表?
ex-serverTimezone=America/New_York。这可以解决许多这样的问题。我相信每次您都需要从应用程序中指定正确的时区,而不考虑DB时区。

您只会得到“错误”吗“时区,还是值本身错误?我将配置更改为使用gmtmillisfordatetimes=true&serverTimezone=GMT。似乎这就是我想要的行为。但是仍然很困惑。请看。谢谢您的useLegacyDatetimeCode建议!注意:这也解决了我在使用Joda Time时遇到的问题(通过usertypes hibernate插件)。因此,在连接字符串中添加serverTimezone和useLegacyDatetimeCode后,我可以发送Timestmp,并将其正确记录在日期时间列中,因为它是UTC时间。我可以在MySQL控制台上看到它。当我通过JDBC进行选择并试图取出数据时,它仍然会在JDBC层自动转换数据。我尝试过getObject()和geTimestmp(无论是否使用UTC日历对象),但它总是在本地时间返回。结果证明,这就是我解决生产问题所需的设置。在当地我们无法复制它。但是,在生产中的驱动程序中尝试此操作消除了我们在处理10-30秒后看到的暂停。@djsumdog-时区信息不存储在Timestamp类中。因此,当您将日期对象打印到控制台时,它将在JVM时区中格式化mysql://localhost?tz=useLegacyDatetimeCode=false&serverTimezone=America/New_York";。对于我的应用程序,此示例链接有效:
url:jdbc:mysql://localhost:3306/trip_planner?tz=useLegacyDatetimeCode=false&serverTimezone=Europe/Berlin
谢谢,这很有效!我还想指出,
IST
没有改变任何东西,而
GMT+1
起了作用。谢谢!我从未估计过我的答案会有任何关联…:-)
useTimezone=true&serverTimezone=GMT%2B8