宽表引擎2.7.6版本之前仅支持东八时区(JVM时区)。 2.7.6版本之后,宽表引擎支持了跨时区特性。本文介绍如何设置当前连接的时区,以确保时间数据与您的期望一致。
背景信息
目前Lindorm支持三种时间类型,其中TIMESTAMP类型和时区相关,DATE、TIME类型和时区无关。
数据类型 | 说明 | 时区特性 |
DATE | 表示年月日,格式为 | 日期字符串,不涉及时区。 |
TIME | 表示时分秒,格式为 | 时间字符串,不涉及时区。 |
TIMESTAMP | 表示年月日时分秒毫秒。格式有以下两种:
|
|
前提条件
宽表引擎为2.7.6及以上版本。如何查看或升级当前版本,请参见宽表引擎版本说明和升级小版本。
如果您的宽表引擎无法通过控制台升级至2.7.6及以上版本,请联系Lindorm技术支持(钉钉号:s0s3eg3)。
使用限制
仅MySQL协议支持设置连接时区。MySQL协议连接方式,请参见使用MySQL协议(推荐)。
设置时区
Lindorm默认时区为东八时区。
设置连接时区仅对当前连接生效。
您可以通过SET time_zone='ZONE'
的语法设置当前连接的时区,对当前连接生效。
设置当前连接时区为UTC时区。
SET @@time_zone='UTC';
设置当前连接时区为+08:00时区。
SET @@time_zone='+08:00';
设置当前连接时区为上海时区(即上海的本地时间)。
SET @@time_zone='Asia/Shanghai';
查询当前时区
SELECT @@time_zone;
示例
MySQL命令行
通过MySQL命令行连接宽表引擎,请参见通过MySQL命令行连接宽表引擎。
假设表tb
的结构、表中数据如下:
-- 创建表
CREATE TABLE tb(p1 int, c1 date, c2 time, c3 timestamp(3), PRIMARY KEY(p1));
-- 插入数据
UPSERT INTO tb(p1,c1,c2,c3) VALUES(1, '2024-08-30', '08:11:15', '2024-08-30 08:11:15.354');
您可以通过以下方式查看和修改连接时区。
查询当前连接的时区。
SELECT @@time_zone;
返回结果:
+-------------+ | @@time_zone | +-------------+ | +08:00 | +-------------+
可以看到当前时区为东八区。
查看当前时区下的时间数据格式。
SELECT * FROM tb;
返回结果:
+------+------------+----------+-------------------------+ | p1 | c1 | c2 | c3 | +------+------------+----------+-------------------------+ | 1 | 2024-08-30 | 08:11:15 | 2024-08-30 08:11:15.354 | +------+------------+----------+-------------------------+
修改当前连接时区为UTC。
SET @@time_zone='UTC';
验证是否修改成功。
SELECT @@time_zone;
返回结果:
+-------------+ | @@time_zone | +-------------+ | UTC | +-------------+
再次查看当前时区下的时间数据格式,验证时区是否修改成功。
SELECT * FROM tb;
返回结果:
+------+------------+----------+-------------------------+ | p1 | c1 | c2 | c3 | +------+------------+----------+-------------------------+ | 1 | 2024-08-30 | 08:11:15 | 2024-08-30 00:11:15.354 | +------+------------+----------+-------------------------+
可以看到DATE和DATE类型的
c1
、c2
列由于与时区无关,因此数据格式无变化。TIMESTAMP类型的c3
列中的数据已变为UTC时区下的日期时间。
Java
Java JDBC连接方式,请参见基于Java JDBC接口的应用开发。
当业务运行在非东八区时,建议您在连接串中添加参数forceConnectionTimeZoneToSession=true
来设置连接时区。具体说明如下:
参数 | 示例值 | 说明 |
connectionTimeZone | UTC | 设置连接时区,默认为客户端运行的JVM时区。如无特殊需要可以不设置。 |
forceConnectionTimeZoneToSession | true | 将connectionTimeZone的值通过 |
连接示例
String url = "jdbc:mysql://ld-uf6k8yqb741t3****-proxy-sql-lindorm-public.lindorm.rds.aliyuncs.com:33060/" + database + "?sslMode=disabled&allowPublicKeyRetrieval=true&useServerPrepStmts=true&useLocalSessionState=true&rewriteBatchedStatements=true&cachePrepStmts=true&prepStmtCacheSize=100&prepStmtCacheSqlLimit=50000000&forceConnectionTimeZoneToSession=true";
Properties properties = new Properties();
properties.put("user", username);
properties.put("password", password);
//获取连接
Connection connection = DriverManager.getConnection(url, properties);
Python
通过mysql-connector-python驱动连接宽表引擎,请参见基于Python的应用开发(mysql-connector-python)。
如果业务运行在UTC时区下,需要在连接串中添加time_zone参数来修改连接时区,使用方式:time_zone='UTC'
。
参数 | 示例值 | 说明 |
time_zone |
| 建议设置为业务运行的系统时区。系统将会通过 |
连接示例:
connection = mysql.connector.connect(host='<MySQL兼容地址>', port=33060, user='<用户名>', passwd='<密码>', database='<数据库名>', time_zone='<时区>')
Go
通过Golang MySQL Driver驱动连接宽表引擎,请参见基于Go的应用开发。
如果业务运行在UTC时区下,需要在连接串中添加loc=Locall&time_zone=%27UTC%27
。具体说明如下:
参数 | 示例值 | 说明 |
parseTime | true |
|
loc | Local | 设置解析 说明 仅设置了 |
time_zone | %27UTC%27 | 设置为业务运行的系统时区。 |
更多说明,请参见系统变量。
连接示例:
urlString := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?timeout=%s&parseTime=true&loc=Local", user, password, host, port, database, connectTimeout)
timeZoneValue := url.QueryEscape("'UTC'")
urlString = urlString + "&time_zone=" + timeZoneValue
db, err := sql.Open("mysql", urlString)
if err != nil {
panic(err.Error())
}