• 【数据库】时区及JDBC的时区设置


    JDBC连接时有个TimeZone配置,这玩意到底有用吗?我是使用Postgresql和Mysql两个数据库验证的。结果如下:

    数据库 部署方式 版本 JDBC连接TimeZone参数 JDBC连接serverTimezone参数 总结
    Mysql docker 8.0 没用 有用,会使用客户端时区与设置的参数时区比较,并返回客户端时区对应的时间,详见实例1 Mysql使用JDBC连接时可以配置serverTimezone参数告诉客户端服务器的时区,因为Mysql的TimeStamp类型是没有时区概念的,且没有timestamp with time zone数据类型,只能通过连接时配置数据库server的时区,并通过两时区的对比,返回正确的客户端时区的时间
    Postgresql docker 15.3 没用 没用 Postgresql使用JDBC连接时,时区参数均无效,但Postgresql有timestamp with time zone数据类型,使用该数据类型时不管数据库是什么时区设置,也不管客户端是什么时区设置,只要你的客户端时区不变,你存取得到的都是同一个时间,该时间的时区取决于客户端的时区。数据库中存储的是对应的UTC时区时间,比如:2023-05-24 00:51:24.578703 +00:00,详见实例2

     

    实例1:

    使用Mysql数据库,建表DDL如下:

    create table test
    (
        a int       null,
        b timestamp null
    );

    数据库中存储的数据:

     使用JDBC连接,不配置serverTimezone参数,客户端时区为东八区,执行以下SQL并用Java Date类型接收输出:

    SELECT b FROM test WHERE a = 1;
    SELECT now();

    输出结果,注意Java的Date类型本身是没有时区属性的,这里之所以输出了CST可以自行研究Date的toString方法:

    Tue May 23 15:13:46 CST 2023
    Wed May 24 01:11:17 CST 2023

    使用JDBC连接,配置serverTimezone参数为serverTimezone=UTC,客户端时区为东八区,执行上面的SQL并用Java Date类型接收输出:

    Tue May 23 23:13:46 CST 2023
    Wed May 24 09:12:52 CST 2023

    总结:

    当不使用serverTimezone配置时,JDBC连接中服务器时区被认为与客户端时区相同,因此数据库中存储的时间返回时被认为是东八区时间,无需变动,但SELECT now();返回的是Mysql服务器时间,即UTC时间。配置serverTimezone参数后,JDBC连接中服务器时区为UTC,客户端时区为东八区,查询数据库中时间被认为是UTC时间,返回给客户端时进行+8小时操作,同时SELECT now();返回值经过时区转换,正确的返回了东八区时间。

     

    实例2:

    使用Postgresql数据库,建表DDL如下:

    create table test
    (
        a integer,
        b timestamp with time zone
    );

    客户端时区为东八区,分别执行以下SQL:

    INSERT INTO test VALUES (2, now());
    SELECT b FROM test WHERE a = 2;
    SELECT now();

    查询结果如下:

    Wed May 24 09:39:39 CST 2023
    Wed May 24 09:39:39 CST 2023

    数据库中存储结果:

    修改客户端时区为东九区,重新执行以上SQL:

    Wed May 24 10:42:17 KST 2023
    Wed May 24 10:42:17 KST 2023

    数据库中存储结果:

    总结:

    使用Postgresql的timestamp with time zone数据类型时,不管数据库是什么时区设置,也不管客户端是什么时区设置,只要你的客户端时区不变,你存取得到的都是同一个时间,该时间的时区取决于客户端的时区。数据库中存储的是转换后的UTC时间。

     

    综上:

    使用Mysql时,JDBC连接中应正确配置serverTimezone参数;使用Postgresql时,使用timestamp with time zone数据类型。来保证获取时间时时区的正确性。

    另外,建议能不用数据库的now()就别用了,数据库时区会搞得你头疼;更近一步,能别用时间(Date)就别用了,时间戳没有时区的概念,当前端需要显示的时候再通过DateFormat或Json转换配置时区即可,可以省去很多需要考虑时区的工作。

     

    以上是我自己的实验结果,如果你有不同的结论,欢迎一起探讨。

  • 相关阅读:
    处理大数据的基础架构,OLTP和OLAP的区别,数据库与Hadoop、Spark、Hive和Flink大数据技术
    贪心算法——硬币找零2——python
    HTML期末作业:基于html+css+javascript+jquery实现古诗词网页 学生网页设计作品 web前端开发技术 web课程设计 网页规划与设计
    Spring Security根据角色在登录后重定向用户
    机器学习排序算法经典模型:RankSVM
    记mapboxGL实现鼠标经过高亮时的一个问题
    基于STM32的烟雾传感器
    C#使用OpenCv(OpenCVSharp)图像中值滤波、高斯滤波、均值滤波、高斯双边滤波处理实例
    Metabase学习教程:权限-2
    算法 反转自符串-(双指针)
  • 原文地址:https://www.cnblogs.com/maerpao/p/17426980.html