当我尝试在连接时设置它时,将mysql中的日期时间和时间戳从默认时区转换为UTC中的UTC不起作用

时间:2015-11-03 19:30:39

标签: java mysql datetime timezone

我正在使用的mysql数据库配置如下:

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

运行数据库的centos机器正在使用PST。

我有一个包含不同时间对象的表格,我想确保当我在我的程序中读取它们时它们处于UTC时间。

描述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 |
+---------------------+---------------------+

以上时间是在PST。

在Java中,我这样连接到DB:

    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");

但是,当我使用上面的查询阅读日期时,它们仍然以PST形式出现。当我提取列时,我可以在Java中转换日期,但有没有办法在连接时执行此操作。我通过修改游标时区在Python中做到了这一点,但是,在Java中,我必须使用PrepareStatement而不是Statement来实现这一点。

我正在使用mysql-connector-java-5.1.36。我曾经遇到类似的问题,当我试图强制执行从拉丁语到UTF-8的编码更改时,我从来没有让它在连接级别工作。同样,在python中我能够实现这一点,但不能用Java实现。

我认为它可能与此语法有关,因此我改变了

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

使用属性。

我怀疑是什么问题,我找不到有关如何补救的证据,告诉我的连接,嘿,服务器在PDT中存储日期,但是当你给我的信息我想要它在UTC。

...谢谢Amro的

事实证明问题的根本原因是select语句将日期对象转换为查询中的字符串:

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

如果删除date_format并保留日期对象,则会发生时区转换。然后,您可以根据需要将日期对象格式化为字符串。但是,要将JVM运行的时区作为转换,因为转换会考虑到这一点。通过TZ设置与DB的连接告诉您的程序数据库中的数据是什么TZ。运行JVM的TZ将决定如何将数据库中的日期/时间转换为程序。您可以将参数传递给JVM或设置默认TZ,以确保您的JVM与其运行的环境无关。

1 个答案:

答案 0 :(得分:0)

事实证明问题的根本原因是select语句将日期对象转换为查询中的字符串:

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

如果删除date_format并保留日期对象,则会发生时区转换。然后,您可以根据需要将日期对象格式化为字符串。但是,要将JVM运行的时区作为转换,因为转换会考虑到这一点。通过TZ设置与DB的连接告诉您的程序数据库中的数据是什么TZ。运行JVM的TZ将决定如何将数据库中的日期/时间转换为程序。您可以将参数传递给JVM或设置默认TZ,以确保您的JVM与其运行的环境无关。