简体   繁体   English

当我尝试在连接时进行设置时,将mysql中的Datetime和时间戳从默认时区转换为Java中的UTC无法正常工作

[英]Convert Datetime and timestamp in mysql from default timezone to UTC in Java is not working when I try to set it at time of connection

The mysql db that I am using is configured as such: 我正在使用的mysql数据库配置如下:

mysql> SELECT @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+
| @@global.time_zone | @@session.time_zone |
+--------------------+---------------------+
| SYSTEM             | SYSTEM              |
+--------------------+---------------------+

The centos machines the database is running on is using PST. 运行数据库的centos计算机正在使用PST。

I have a table with different time objects that I want to make sure that when i read them in my program they are in UTC time. 我有一个包含不同时间对象的表,我想确保当我在程序中读取它们时,它们处于UTC时间。

describe mytable: 描述mytable:

| start_date    | timestamp           | NO   | MUL | CURRENT_TIMESTAMP   |                     
| update_date   | datetime            | YES  | MUL | NULL                |           

select start_date, update_date from mytable limit 1;

+---------------------+---------------------+
| start_date          | update_date         |
+---------------------+---------------------+
| 2015-11-02 07:42:15 | 2015-11-02 07:48:40 |
+---------------------+---------------------+

The above times are in PST. 以上时间是太平洋标准时间(PST)。

In Java, I connect to the DB as such: 在Java中,我这样连接到数据库:

    String dbStr = String.format("jdbc:mysql://%s:%d/%s", sqlHost, sqlPort, sqlDb);

    Properties connectionProps = new Properties();
    connectionProps.put("user", USER);
    connectionProps.put("password", PASSWORD);
    connectionProps.put("useLegacyDatetimeCode", "false");
    connectionProps.put("serverTimezone", "UTC");

However, when I read the dates using the query above, they still come out as PST. 但是,当我使用上面的查询读取日期时,它们仍然以PST形式出现。 I could convert the dates later on in Java when I extract the columns, but is there a way to do this at connection time. 当我提取列时,可以稍后在Java中转换日期,但是有一种方法可以在连接时进行。 I did this in Python by modifying the cursor timezone, however, in Java I would have to use PrepareStatement instead of Statement to even achieve this. 我在Python中通过修改游标时区来做到这一点,但是在Java中,我什至必须使用PrepareStatement而不是Statement来实现此目的。

I am using mysql-connector-java-5.1.36. 我正在使用mysql-connector-java-5.1.36。 I have had a similar issue in the past when I was trying to enforce an encoding change from latin to UTF-8 and I never got it to work at the connection level. 过去,当我尝试将编码更改从拉丁语更改为UTF-8时遇到过类似的问题,但我从未在连接级别上使它生效。 Again, in python I was able to achieve this but not in Java. 同样,在python中我能够实现这一点,但在Java中却没有。

I thought it might be related to this syntax and hence why I changed from 我认为这可能与这种语法有关,因此为什么我从

String.format("jdbc:mysql://%s:%d/%s?useLegacyDatetimeCode=false&serverTimezone=UTC", sqlHost, sqlPort, sqlDb)

to using properties. 使用属性。

What I suspect is the issue and I could not find evidence on how to remedy that is telling my connection that hey, the server is storing dates in PDT, but when you give me the info I want it in UTC. 我怀疑是问题所在,我找不到有关如何补救的证据,这告诉我连接,服务器正在PDT中存储日期,但是当您给我信息时,我希望以UTC形式存储。

Thanks...Amro 谢谢...荷银

It turns out the root cause of the issue is that the select statement was converting the date objects to string within the query: 事实证明,问题的根本原因是select语句将日期对象转换为查询中的字符串:

SELECT date_format(start_date, '%Y-%m-%dT%H:%i:%s'), 
       date_format(update_date, '%Y-%m-%dT%H:%i:%s') from myTable;

If you remove the date_format and preserve the date object, the timezone conversions take place. 如果删除date_format并保留date对象,则会进行时区转换。 You can then format the date objects as strings as you see fit. 然后,您可以根据需要将日期对象格式化为字符串。 However, be ware of the timezone your JVM is running in as the conversion takes that into account. 但是,请注意转换时会考虑到您的JVM运行所在的时区。 The connection to the DB with the TZ setup tells your program what TZ the data in the DB is in. The TZ your JVM is running in will determine how to convert the date/time from the db into your program. 使用TZ设置与数据库的连接将告诉您的程序数据库中数据所在的TZ。您的JVM运行所在的TZ将确定如何将日期/时间从数据库转换为程序。 You can pass a parameter to the JVM or set the default TZ to ensure your JVM is agnostic to the environment it is running in. 您可以将参数传递给JVM或设置默认的TZ,以确保您的JVM与运行它的环境无关。

It turns out the root cause of the issue is that the select statement was converting the date objects to string within the query: 事实证明,问题的根本原因是select语句将日期对象转换为查询中的字符串:

SELECT date_format(start_date, '%Y-%m-%dT%H:%i:%s'), 
       date_format(update_date, '%Y-%m-%dT%H:%i:%s') from myTable;

If you remove the date_format and preserve the date object, the timezone conversions take place. 如果删除date_format并保留date对象,则会进行时区转换。 You can then format the date objects as strings as you see fit. 然后,您可以根据需要将日期对象格式化为字符串。 However, be ware of the timezone your JVM is running in as the conversion takes that into account. 但是,请注意转换时会考虑到您的JVM运行所在的时区。 The connection to the DB with the TZ setup tells your program what TZ the data in the DB is in. The TZ your JVM is running in will determine how to convert the date/time from the db into your program. 使用TZ设置与数据库的连接将告诉您的程序数据库中数据所在的TZ。您的JVM运行所在的TZ将确定如何将日期/时间从数据库转换为程序。 You can pass a parameter to the JVM or set the default TZ to ensure your JVM is agnostic to the environment it is running in. 您可以将参数传递给JVM或设置默认的TZ,以确保您的JVM与运行它的环境无关。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM