如何设置连接时区

宽表引擎2.7.6版本之前仅支持东八时区(JVM时区)。 2.7.6版本之后,宽表引擎支持了跨时区特性。本文介绍如何设置当前连接的时区,以确保时间数据与您的期望一致。

背景信息

目前Lindorm支持三种时间类型,其中TIMESTAMP类型和时区相关,DATE、TIME类型和时区无关。

数据类型

说明

时区特性

DATE

表示年月日,格式为yyyy-mm-dd,例如2024-08-30

日期字符串,不涉及时区。

TIME

表示时分秒,格式为hh:mm:ss,例如08:11:15

时间字符串,不涉及时区。

TIMESTAMP

表示年月日时分秒毫秒。格式有以下两种:

  • yyyy-mm-dd hh:mm:ss.SSS,例如2024-08-30 08:11:15.354, 精确到毫秒。

  • epoch毫秒时间戳,类型为长整型,例如1724976675345

  • 日期+时间字符串,与时区相关,表示当前时区的时间+日期。

  • 长整型的毫秒时间戳表示从UTC时区1970年1月1日00:00:00开始的毫秒数。

前提条件

宽表引擎为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');

您可以通过以下方式查看和修改连接时区。

  1. 查询当前连接的时区。

    SELECT @@time_zone;

    返回结果:

    +-------------+
    | @@time_zone |
    +-------------+
    | +08:00      |
    +-------------+

    可以看到当前时区为东八区。

  2. 查看当前时区下的时间数据格式。

    SELECT * FROM tb;

    返回结果:

    +------+------------+----------+-------------------------+
    | p1   | c1         | c2       | c3                      |
    +------+------------+----------+-------------------------+
    |    1 | 2024-08-30 | 08:11:15 | 2024-08-30 08:11:15.354 |
    +------+------------+----------+-------------------------+
  3. 修改当前连接时区为UTC。

    SET @@time_zone='UTC';
  4. 验证是否修改成功。

    SELECT @@time_zone;

    返回结果:

    +-------------+
    | @@time_zone |
    +-------------+
    | UTC         |
    +-------------+
  5. 再次查看当前时区下的时间数据格式,验证时区是否修改成功。

    SELECT * FROM tb;

    返回结果:

    +------+------------+----------+-------------------------+
    | p1   | c1         | c2       | c3                      |
    +------+------------+----------+-------------------------+
    |    1 | 2024-08-30 | 08:11:15 | 2024-08-30 00:11:15.354 |
    +------+------------+----------+-------------------------+

    可以看到DATE和DATE类型的c1c2列由于与时区无关,因此数据格式无变化。TIMESTAMP类型的c3列中的数据已变为UTC时区下的日期时间。

Java

Java JDBC连接方式,请参见基于Java JDBC接口的应用开发

当业务运行在非东八区时,建议您在连接串中添加参数forceConnectionTimeZoneToSession=true来设置连接时区。具体说明如下:

参数

示例值

说明

connectionTimeZone

UTC

设置连接时区,默认为客户端运行的JVM时区。如无特殊需要可以不设置。

forceConnectionTimeZoneToSession

true

connectionTimeZone的值通过set time_zone语句设置到服务端。业务运行在非东八区时,建议添加该参数。

连接示例

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

'UTC'

建议设置为业务运行的系统时区。系统将会通过set 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

parseTime=true可以将DATE 和TIMESTAMP类型的数据输出为time.Time类型。

loc

Local

设置解析 time.Time 类型时的时区,设置为Local表示使用系统时区。

说明

仅设置了parseTime=true时,该参数生效。

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())
}