我使用的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 |
+---------------------+---------------------+
以上时间为太平洋标准时间。
在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并保留date对象,则会进行时区转换。然后,您可以将日期对象格式化为您认为合适的字符串。但是,要注意JVM运行的时区,因为转换会考虑到这一点。通过TZ设置与数据库的连接告诉程序数据库中的数据所在的TZ。JVM运行的TZ将决定如何将数据库中的日期/时间转换为程序。您可以向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并保留date对象,则会进行时区转换。然后,您可以将日期对象格式化为您认为合适的字符串。但是,要注意JVM运行的时区,因为转换会考虑到这一点。通过TZ设置与数据库的连接告诉程序数据库中的数据所在的TZ。JVM运行的TZ将决定如何将数据库中的日期/时间转换为程序。您可以向JVM传递一个参数或设置默认TZ,以确保JVM对其运行的环境是不可知的。