将 mysql 中的日期时间和时间戳从默认时区转换为 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

我使用的 mysql 数据库是这样配置的:

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

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

我有一个 table 具有不同的时间对象,我想确保当我在我的程序中读取它们时它们是 UTC 时间。

描述我的table:

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

以上时间为太平洋标准时间

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

但是,当我使用上面的查询读取日期时,它们仍然显示为太平洋标准时间。当我提取列时,我可以稍后在 Java 中转换日期,但是有没有办法在连接时执行此操作。我在 Python 中通过修改游标时区来完成此操作,但是,在 Java 中我将不得不使用 PrepareStatement 而不是 Statement 来实现此目的。

我正在使用 mysql-连接器-java-5.1.36。过去,当我试图强制将编码从拉丁语更改为 UTF-8 时,我遇到过类似的问题,但我从未让它在连接级别工作。同样,在 python 中我能够实现这一点,但在 Java.

中却没有

我认为这可能与此语法有关,因此我从

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

使用属性。

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

谢谢...阿姆罗

原来问题的根本原因是 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 设置与数据库的连接告诉您的程序数据库中的数据在哪个 TZ 中。您的 JVM 运行 所在的 TZ 将决定如何将 date/time 从数据库转换到您的程序中.您可以将参数传递给 JVM 或设置默认 TZ 以确保您的 JVM 与它所在的环境无关运行。

原来问题的根本原因是 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 设置与数据库的连接告诉您的程序数据库中的数据在哪个 TZ 中。您的 JVM 运行 所在的 TZ 将决定如何将 date/time 从数据库转换到您的程序中.您可以将参数传递给 JVM 或设置默认 TZ 以确保您的 JVM 与它所在的环境无关运行。