java代码中设置mysql时区_关于Java中的mysql时区问题详解

2023-11-10

前言

话说工作十多年,mysql 还真没用几年。起初是外企银行,无法直接接触到 DB;后来一直从事架构方面,也多是解决问题为主。

这次搭建海外机房,围绕时区大家做了一番讨论。不说最终的结果是什么,期间有同事认为 DB 返回的是 UTC 时间。

这里简单做个验证,顺便看下时区的问题到底是如何处理。

环境

openjdk version “1.8.0_242”

mysql-connector-Java “8.0.20”

mysql “5.7” 时区 TZ=Europe/London

本地时区 GMT+8

创建个简单的库test及表user, 表结构如下: CREATE TABLE `user` (

`name` varchar(50) NOT NULL,

`birth_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP

) ENGINE=InnoDB DEFAULT CHARSET=latin1

插入一条测试数据: mysql> insert into `user`

-> values ('Tom', time('2020-05-15 08:00:00'));

Query OK, 1 row affected (0.01 sec)

mysql> select * from user;

+------+---------------------+

| name | birth_date |

+------+---------------------+

| Tom | 2020-05-14 08:00:00 |

+------+---------------------+

1 row in set (0.00 sec)

测试代码: Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?useSSL=false", "root", "root");

Statement stmt = conn.createStatement();

stmt.execute("select * from user where name = 'Tom'");

ResultSet rs = stmt.getResultSet();

while (rs.next()) {

Timestamp timestamp = rs.getTimestamp("birth_date");

System.out.println(timestamp.toLocalDateTime().toString());

}

执行结果:

2020-05-14T15:00

分析

程序的执行过程同时用 wireshark 抓了包。可以看到一次查询,做了这么多次的交互(包含了会话初始化)。这里可以看到 #177 的交互返回查询的结果:Tom 2020-05-14 08:00:00,与 DB 中的数据相符。可见,返回的并不是 UTC 时间。

d5389e57be6fa1b6e579006c6fedd69c.png

在 TCP 抓包结果中 #155 的查询语句: /* mysql-connector-java-8.0.20 (Revision: afc0a13cd3c5a0bf57eaa809ee0ee6df1fd5ac9b) */

SELECT @@session.auto_increment_increment AS auto_increment_increment,

@@character_set_client AS character_set_client,

@@character_set_connection AS character_set_connection,

@@character_set_results AS character_set_results,

@@character_set_server AS character_set_server,

@@collation_server AS collation_server,

@@collation_connection AS collation_connection,

@@init_connect AS init_connect,

@@interactive_timeout AS interactive_timeout,

@@license AS license,

@@lower_case_table_names AS lower_case_table_names,

@@max_allowed_packet AS max_allowed_packet,

@@net_write_timeout AS net_write_timeout,

@@performance_schema AS performance_schema,

@@query_cache_size AS query_cache_size,

@@query_cache_type AS query_cache_type,

@@sql_mode AS sql_mode,

@@system_time_zone AS system_time_zone,

@@time_zone AS time_zone,

@@transaction_isolation AS transaction_isolation,

@@wait_timeout AS wait_timeout;

794bd0ce4b66574054b3f8cb9b25a730.png

服务端返回的 time_zone 为 BST。与本地时区的转换,由 mysql 的 connector 自动完成。

进阶

时区自动转换

实现源码:

ResultSetImpl源码 this.defaultTimestampValueFactory = new SqlTimestampValueFactory(pset, null, this.session.getServerSession().getServerTimeZone());@Overridepublic Timestamp getTimestamp(int columnIndex) throws SQLException {

checkRowPos();

checkColumnBounds(columnIndex); return this.thisRow.getValue(columnIndex - 1, this.defaultTimestampValueFactory);

}

如何确认服务端时区?

使用会话中的服务端时区进行服务端时区。会话初始化时会进行时区的确认,比如前面获取的到BST。确认时区的逻辑在NativeProtocol#configureTimezone()中: public void configureTimezone() {

#从mysql的响应获取 time_zone 和 system_time_zone 的设置

String configuredTimeZoneOnServer = this.serverSession.getServerVariable("time_zone");

if ("SYSTEM".equalsIgnoreCase(configuredTimeZoneOnServer)) {

configuredTimeZoneOnServer = this.serverSession.getServerVariable("system_time_zone");

}

#从 jdbc url 参数 serverTimezone 获取时区

String canonicalTimezone = getPropertySet().getStringProperty(PropertyKey.serverTimezone).getValue();

if (configuredTimeZoneOnServer != null) {

//如果 jdbc url 中未通过 serverTimezone 指定时区。则从TimeZoneMapping.properties中获取mysql 回传的时区缩写对应的标准时区,比如此处的 BST => Europe/London

//会出现无法映射的情况,不如 CEST 无法映射到 => Europe/Berlin,可以指定自定义的 Properties 文件进行映射

// user can override this with driver properties, so don't detect if that's the case

if (canonicalTimezone == null || StringUtils.isEmptyOrWhitespaceOnly(canonicalTimezone)) {

try {

canonicalTimezone = TimeUtil.getCanonicalTimezone(configuredTimeZoneOnServer, getExceptionInterceptor());

} catch (IllegalArgumentException iae) {

throw ExceptionFactory.createException(WrongArgumentException.class, iae.getMessage(), getExceptionInterceptor());

}

}

}

//如果 jdbc url 中通过 serverTimezone 指定了时区,则优先使用该时区

if (canonicalTimezone != null && canonicalTimezone.length() > 0) {

this.serverSession.setServerTimeZone(TimeZone.getTimeZone(canonicalTimezone));

//

// The Calendar class has the behavior of mapping unknown timezones to 'GMT' instead of throwing an exception, so we must check for this...

//

if (!canonicalTimezone.equalsIgnoreCase("GMT") && this.serverSession.getServerTimeZone().getID().equals("GMT")) {

throw ExceptionFactory.createException(WrongArgumentException.class, Messages.getString("Connection.9", new Object[] { canonicalTimezone }),

getExceptionInterceptor());

}

}

}

关于 serverTimezone 的官方说明

Override detection/mapping of time zone. Used when time zone from server doesn't map to Java time zone

修改一下 jdbc url,通过serverTimezone指定时区为 GMT+8:jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8&useSSL=false

再次执行代码:

2020-05-14T08:00

总结

到此这篇关于关于Java中mysql时区问题的文章就介绍到这了,更多相关Java中mysql时区问题内容请搜索聚米学院以前的文章或继续浏览下面的相关文章希望大家以后多多支持聚米学院!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java代码中设置mysql时区_关于Java中的mysql时区问题详解 的相关文章

  • 关于sshd服务无法开启的问题集合

    SSHD服务开启问题集合 报错1 错误 systemctl restart sshd Failed to restart sshd service Interactive authentication required See system
  • 沈师 PTA 数据库题目及部分解析 第一章

    判断题 1 一个数据库只有一个模式和一个内模式 T 2 数据模型是由数据结构 数据操作和完整性约束三部分组成的 T 3 由于数据库中的数据是不断更新的 因此关系模式是相对变化的 F 解析 关系模式不会相对变化 变化的是实例 4 数据库中的数
  • linux中vim/gvim的安装与verilog,systemverilog语法高亮显示

    linux中vim gvim的安装参考如下链接 https blog csdn net Stone Age article details 47276995 utm source blogxgwz8 安装完后 在用户目录下vim和gvim都
  • SpringBoot集成redis

    一 下载安装redis 1 官网地址 https redis io 2 GitHub地址 https github com MicrosoftArchive redis tags 3 安装 自行安装 二 SpringBoot集成redis
  • 【odoo】创建带用户类型的odoo用户,基于xml

  • 3dmax卡顿、卡死 怎么解决?

    一般3dmax容易卡 主要有下面几个原因 1 Win10自带的微软输入法引起的 2 3dmax病毒引起的 3 3d场景太多垃圾引起的 4 模型太大 5 显卡驱动或显示模式不正确 如果是Win10自带的微软输入法引起的 只需要将Win10下面
  • 【web漏洞】PHP反序列化

    目录 知识点 反序列化常用方法 序列化的 构造payload 运行顺序 反序列化的 实现payload 运行顺序 绕过 wakeup tostring 知识点 序列化 serialize 对象的状态信息转换为可以存储或传输的形式的过程 在序
  • CUDA_NVCC_FLAGS set

    NVIDIA CUDA C 编译器 nvcc 基于每个内核 既可以用来产生特定于体系结构的 cubin 文件 又能产生前向兼容的 PTX 版本 每个 cubin 文件针对特定的计算能力版本 并且仅与相同主要版本号的 GPU 架构向前兼容 例
  • 网页制作神器—ElementUI(小白入门超详细)

    目录 一 前置准备 初始化Vue 项目 二 引入ElementUI 三 使用ElementUI 一 前置准备 1 安装相关环境 使用VsCode或者webstrom初始化Vue 项目 软件环境下载地址 软件 坚果云 同步 备份 无限空间 v
  • 一些工具类

    1 字符串处理工具类 1 1 StrUtils package com study java8 util Classname StrUtils Description 字符串工具类 Date 2023 9 9 9 37 Author jsz
  • Windows7 64位系统下安装 latex:texlive2019 和 texstudio

    1 下载及安装texlive2019 a 网上下载方法很多 TeX套装下载来这里 http www latexstudio net texsoftware b https www tug org texlive c https mirror
  • Ubuntu+Python环境做上位机

    最近需要制作程控电阻箱的上位机 使得大学毕业后就不再接触硬件的我无从下手 拿到机器后不知道怎么与其进行通信 Google上的资料也很少 现将我的环境搭建过程记录下来 希望对和我一样的小白有所帮助 软件环境 Ubuntu 16 04 pyth
  • AcWing4908. 饥饿的牛

    输入样例1 1 5 1 2 输出样例1 2 样例1解释 两捆干草在第 11 天早上被送到了牛棚 所以贝茜第 1 2 天有干草吃 输入样例2 2 5 1 2 5 10 输出样例2 3 样例2解释 两捆干草在第 1 天早上被送到了牛棚 所以贝茜
  • Spring简述

    Sping是什么 Spring主要模块 IOC DI依赖注入的三种方式 AOP 术语 Sping是什么 Spring是一个轻量级的开源框架 主要作用是为了简化开发 它以IOC 控制反转 和AOP 面向切面编程 为内核 Spring主要模块
  • 计算机辅助教学考博,2018年华中科技大学3319计算机辅助设计与制造考博大纲

    资源大小 0 1 10 0 MB 资源类型 rar 发布时间 2020 5 14 23 35 45 资源评分 资源简介 2018年华中科技大学3319计算机辅助设计与制造考博大纲 下载流程 考研真题 点击 考研试卷 下载 考博真题 点击 考
  • 物理机ubuntu系统--远程控制-不接显示器-使用虚拟显示器-设置分辨率1920*1080

    liunx系统与intel显卡驱动不兼容的机制问题 导致有些机器无法在没有显示器的情况下 不能进行远程 向日葵和TeamViewer都不行 因此使用虚拟显示器的软件Xorg 反正网上很多资料 本文只是添加图片 更加详细的过程 以及遇到的情况
  • STM32开发笔记02---新建库函数工程

    架构图 创建工程 首先我们先创建一个资料夹example 路径最好配置为全英文 然后分别在example资料夹内再创建6个资料夹 分别是 Doc Libraries Listing Output Project User 然后开启keil
  • Ethereum账户私钥管理之导出、导出keystore 文件

    目录 前言 一 理解keystore文件的导出 导入 二 导出keystore文件 三 导入keystore文件 并还原成为私钥
  • 软件体系结构实验报告-比较不同的软件架构风格

    报告内容 调试分析KWIC 理解不同架构风格 1 画出每一种风格对应程序的静态结构图 如类图 2 打印出程序的执行过程 3 使用一个较大的输入文本 测试每一种风格程序的性能 4 结合程序 总结每一种架构风格的特点 一 画出每一种风格对应程序

随机推荐

  • JS中将数组作为值添加到对象中

    1 条件 已有对象 myobject key1 value1 key2 value2 key3 value3 已有数组 myarray 1 2 3 4 5 6 2 需求 myobject key1 value1 key2 value2 ke
  • Windows删除Maven本地资源库中lastUpdate和repositories文件的脚本

    一 脚本 1 删除 lastUpdated的文件的脚本 1 在桌面新建txt文档 将后缀改为 bat 文件名称随意 2 添加内容如下 echo off set REPOSITORY PATH C softwore apache maven
  • 02.02.19

    做一件事开始觉得痛苦 别怕继续做下去 因为你已经进入到一个新的阶段 你在融入 因为这种痛苦是付出过的人才体会的到的 开始变得轻松但发现自己更渺小又是一个阶段 你已经融入了 继续的就是坚持 保持一颗 幼稚 上进 的心 走到最后 转载于 htt
  • VUE 实现两个select联动效果

    两个下拉框 当选择A的时候B会跟着联动 template代码
  • docker安装ros的一点记录

    docker本没有图形化界面 但是ros很多时候都要用到rviz来看数据 比较烦人的一件事情 ros的镜像本身的图形化显示本身给人一种没有做完的感觉 需要再做些事情才能正确显示 首先 ros的rviz显示需要opengl的正确支持 而ope
  • mysql [42000][1071] Specified key was too long; max key length is 767 bytes

    今天在MySQL中建立表的时候 报了一个错误 说是key太长了 超戳了767个字节 但是建表语句并有超过指定的长度啊 CREATE TABLE XXL JOB QRTZ JOB DETAILS SCHED NAME VARCHAR 120
  • (二)Ubuntu系统Pytorch环境配置

    1 前言 2 安装miniconda 3 安装Pytorch 4 安装CUDA和cuDNN 5 验证 环境配置系列 一 Ubuntu安装详细教程 从镜像制作到NVIDIA驱动安装全流程 超详细的图文教程 二 Ubuntu系统Pytorch环
  • 图解算法使用python吴灿铭 pdf_图解算法

    像小说一样有趣的算法入门书 算法是解决问题的一步步流程 也是计算机科学领域的核心主题 如今程序员 常用的算法已经经过了前人的探索 检验及证明 如果你想搞明白这些算法 又不想被困在繁琐的证明中 本书正是你的不二选择 这本图示丰富 引人入胜的实
  • 【数据结构】零基础树状数组笔记

    参考和引用 树状数组学习笔记 树状数组 数据结构详解与模板 可能是最详细的了 树状数组 简单介绍 树状数组小结 AcWing 241 楼兰图腾 的题解 树状数组求逆序对模板 转 树状数组逆序对 树状数组的作用 树状数组 也叫做二叉索引树 或
  • CMake 入门与进阶

    目录 cmake简介 cmake的下载 cmake 的使用方法 示例一 单个源文件 cmake生成的中间文件以及可执行文件都放在build目录下 示例二 多个源文件 示例三 生成库文件 动态库和静态库 修改库文件名字 最低版本要求 示例四
  • Set接口介绍

    文章目录 前言 一 Set接口 1 Set接口特点 2 Set的实现类 Set接口提供的方法API 二 HashSet 1 HashSet的特点 2 HashSet的属性 3 HashSet的构造函数 4 HashSet方法 三 Linke
  • java中的循环

    java中的循环有四种 循环由四部分组成 1 初始部分 循环判断的变量 2 循环条件 布尔表达式 3 循环操作 循环执行的代码 4 迭代部分 更新循环变量 1 while循环 while的特点 首次判断不满足 则一次都不会执行 先判断 再执
  • 渗透测试之指纹识别(CMS、CDN、WAF)

    目录 什么是指纹识别 1 cms指纹识别 2 cdn指纹识别 3 WAF指纹识别 什么是指纹识别 通过关键特征 识别出目标的CMS系统 服务器 开发语言 操作系统 CDN WAF的类别 版本等等 其中主要识别以下的信息 1 CMS信息 比如
  • C3PO数据库连接池

    一 数据库连接池原理 连接池基本的思想是在系统初始化的时候 将数据库连接作为对象存储在内存中 当用户需要访问数据库时 并非建立一个新的连接 而是从连接池中取出一个已建立的空闲连接对象 使用完毕后 用户也并非将连接关闭 而是将连接放回连接池中
  • Adversarial Visual Robustness by Causal Intervention

    Motivation 机器能够利用人看不见的pattern对目标进行分类 当测试时pattern不变 那么这些pattern是有益的 被称为predictive features 而当他们在攻击中被篡改时 他们就是混淆因子 本文希望通过因果
  • 【C++】《C++标准程序库》小结第九章-算法

    1 普通算法在
  • 软件测试从月薪8k到年薪30W+,一个女测工的辛苦历程

    我花了6年的时间 由月薪8k的手工测试成长到年薪30w 的测试开发 回顾我从手工测试到测试开发的成长路径 基本上是伴随着 3次能力飞跃 实现的 第一次 能力飞跃 从不满足现状开始 第一家入职的时候是一家小公司 工资给了8K多点 刚开始入行的
  • shopify店铺 怎么样 shopify建站 我的使用经验

    公司从19年底开始使用shopify建站 进行品牌宣传和商城交易的相关业务 我个人作为开发也从开发shopify的工作中学习到了很多东西 这个框架非常灵活 官方也提供了很多接口 优点 主题编辑器 可以实时预览编辑 开发灵活 可扩展性强 插件
  • SoapUI经常遇到的问题记录--持续刷新

    1 怎么SoapUI的Request URL不支持大写怎么办 问题 在SoapUI的Request URL中 每次输入的URL中含有的大写字母会自动转换为小写字母 导致请求不了对应的地址该怎么办 解决方法 具体的解决办法是在HTTP Tes
  • java代码中设置mysql时区_关于Java中的mysql时区问题详解

    前言 话说工作十多年 mysql 还真没用几年 起初是外企银行 无法直接接触到 DB 后来一直从事架构方面 也多是解决问题为主 这次搭建海外机房 围绕时区大家做了一番讨论 不说最终的结果是什么 期间有同事认为 DB 返回的是 UTC 时间