r2dbc指定时区问题

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: r2dbc指定时区问题

政治能把一个人突然变老——巴尔扎克

今天看见这个警告

我的配置项如下:

import cn.hutool.core.util.StrUtil;
import com.alibaba.druid.util.JdbcUtils;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
import io.r2dbc.spi.ConnectionFactories;
import io.r2dbc.spi.ConnectionFactory;
import io.r2dbc.spi.ConnectionFactoryOptions;
import io.r2dbc.spi.Option;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import java.time.Duration;
import java.util.Map;
import static io.r2dbc.spi.ConnectionFactoryOptions.*;
@Configuration
public class R2dbcConfig {
  @Bean
    public ConnectionFactory connectionFactory(DynamicDataSourceProperties dataSource) {
        Map<String, DataSourceProperty> datasourceMap = dataSource.getDatasource();
        DataSourceProperty master = datasourceMap.get("master");
        String host = StrUtil.subBetween(master.getUrl(), "mysql://", ":");
        String port = StrUtil.subBetween(master.getUrl(), host + ":", "/");
        String database = StrUtil.subBetween(master.getUrl(), port + "/", "?");
        ConnectionFactoryOptions options = ConnectionFactoryOptions.builder()
                .option(DRIVER, JdbcUtils.MYSQL)
                .option(HOST, host)
                .option(USER, master.getUsername())
                .option(PORT, Integer.valueOf(port))  // optional, default 3306
                .option(PASSWORD, master.getPassword()) // optional, default null, null means has no password
                .option(DATABASE, database) // optional, default null, null means not specifying the database
                .option(CONNECT_TIMEOUT, Duration.ofSeconds(3)) // optional, default null, null means no timeout
                .option(Option.valueOf("socketTimeout"), Duration.ofSeconds(4)) // optional, default null, null means no timeout
                .option(SSL, false) // optional, default sslMode is "preferred", it will be ignore if sslMode is set
                .option(Option.valueOf("zeroDate"), "use_null") // optional, default "use_null"
                .option(Option.valueOf("useServerPrepareStatement"), true) // optional, default false
                .option(Option.valueOf("tcpKeepAlive"), true) // optional, default false
                .option(Option.valueOf("tcpNoDelay"), true) // optional, default false
                .option(Option.valueOf("autodetectExtensions"), false) // optional, default false
                .build();
        ConnectionFactory connectionFactory = ConnectionFactories.get(options);
        return connectionFactory;
    }
}

我想到能在这里配置时区,于是按照警告提示的timezone配置发现不生效、换成serverTimezone依旧不行

issue,没有(这里其实是搜错仓库了,正确的仓库是这个https://github.com/mirromutth/r2dbc-mysql ,在readme里就提到了时区配置)

翻阅文档,没找到:https://r2dbc.io/

看警告的代码行数dev.miku.r2dbc.mysql.MySqlConnection:451

然后发现调用convertZoneId的地方在97100

于是debug,这个timeZonesystemTimeZone都是从row获取到的

看到确实拿到的是乱码

row里找到了zeroDateOption,因为我们上面配置了zeroDateuse_null,我有印象

所以看到这里的serverZoneId,就试着配置了一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Bean
public ConnectionFactory connectionFactory(DynamicDataSourceProperties dataSource) {
    Map<String, DataSourceProperty> datasourceMap = dataSource.getDatasource();
DataSourcePropertymaster= datasourceMap.get("master");
Stringhost= StrUtil.subBetween(master.getUrl(), "mysql://", ":");
Stringport= StrUtil.subBetween(master.getUrl(), host + ":", "/");
Stringdatabase= StrUtil.subBetween(master.getUrl(), port + "/", "?");
ConnectionFactoryOptionsoptions= ConnectionFactoryOptions.builder()
            .option(DRIVER, JdbcUtils.MYSQL)
            .option(HOST, host)
            .option(USER, master.getUsername())
            .option(PORT, Integer.valueOf(port))  // optional, default 3306
            .option(PASSWORD, master.getPassword()) // optional, default null, null means has no password
            .option(DATABASE, database) // optional, default null, null means not specifying the database
            .option(CONNECT_TIMEOUT, Duration.ofSeconds(3)) // optional, default null, null means no timeout
            .option(Option.valueOf("socketTimeout"), Duration.ofSeconds(4)) // optional, default null, null means no timeout
            .option(SSL, false) // optional, default sslMode is "preferred", it will be ignore if sslMode is set
            .option(Option.valueOf("zeroDate"), "use_null") // optional, default "use_null"
            .option(Option.valueOf("useServerPrepareStatement"), true) // optional, default false
            .option(Option.valueOf("tcpKeepAlive"), true) // optional, default false
            .option(Option.valueOf("tcpNoDelay"), true) // optional, default false
            .option(Option.valueOf("autodetectExtensions"), false) // optional, default false
            .option(Option.valueOf("serverZoneId"), TimeZone.getTimeZone("GMT+8").getID()) // optional
            .build();
ConnectionFactoryconnectionFactory= ConnectionFactories.get(options);
return connectionFactory;
}

然后生效了,不再打印该警告

后来发现github人家写了配置项,我自己没找到

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
Linux 数据库 容器
Centos中将UTC的时区改为CTS时区
通过以上步骤,您就可以顺利地在CentOS系统中完成时区从UTC到中国标准时间(Asia/Shanghai)的更改了。
85 1
|
7月前
|
存储 关系型数据库 MySQL
MySQL 格式化日期函数 DATE_FORMAT(), FROM_UNIXTIME() 和 UNIX_TIMESTAMP() 之间区别
MySQL 格式化日期函数 DATE_FORMAT(), FROM_UNIXTIME() 和 UNIX_TIMESTAMP() 之间区别
213 1
|
7月前
|
数据库连接
数据库连接的时区问题 The server time zone value is unrecognized
数据库连接的时区问题 The server time zone value is unrecognized
110 0
|
关系型数据库 MySQL
使用mysqldump 导出 含有timestamp类型的表,应注意--skip-tz-utc
使用mysqldump 导出 含有timestamp类型的表,应注意--skip-tz-utc
61 0
|
关系型数据库 MySQL Java
TimeZone-datetime在JVM时区和MySQL Session时区的转换
TimeZone-datetime在JVM时区和MySQL Session时区的转换
172 0
|
SQL 关系型数据库
Postgre SQL date_trunc() 和timestamp
Postgre SQL date_trunc() 和timestamp
117 0
|
SQL
SQL SERVER-时间戳(timestamp)与时间格式(datetime)互相转换
原文:SQL SERVER-时间戳(timestamp)与时间格式(datetime)互相转换 SQL里面有个DATEADD的函数。时间戳就是一个从1970-01-01 08:00:00到时间的相隔的秒数。
14143 0
|
关系型数据库 MySQL
MySQL:date_format格式化时间格式
MySQL:date_format格式化时间格式
140 0
|
存储 关系型数据库 MySQL
mysqldump中skip-tz-utc参数介绍
在前面文章中,有提到过 mysqldump 备份文件中记录的时间戳数据都是以 UTC 时区为基础的,在筛选恢复单库或单表时要注意时区差别。后来再次查看文档,发现 tz-utc、skip-tz-utc 参数与此有关,本篇文章我们一起来看下此参数的作用吧。
186 0
|
SQL Oracle 关系型数据库
ORACLE NLS_DATE_FORMAT设置
最近在ORACLE里面设置NLS_DATE_FORMAT日期时间格式时遇到了一些问题,顺便整理一下。以防以后忘记时,能顺速翻阅。     1:在会话级别设置nls_date_format对应的日期格式。
1601 0