电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

關于Java中的mysql時區問題詳解

瀏覽:66日期:2022-09-01 10:42:01

前言

話說工作十多年,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 時間。

關于Java中的mysql時區問題詳解

在 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_packetAS max_allowed_packet, @@net_write_timeoutAS net_write_timeout, @@performance_schemaAS 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;

關于Java中的mysql時區問題詳解

服務端返回的 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時區問題內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Java
相關文章:
主站蜘蛛池模板: 雾度仪_雾度计_透光率雾度仪价格-三恩时(3nh)光电雾度仪厂家 | 昆明网络公司|云南网络公司|昆明网站建设公司|昆明网页设计|云南网站制作|新媒体运营公司|APP开发|小程序研发|尽在昆明奥远科技有限公司 | 小型UV打印机-UV平板打印机-大型uv打印机-UV打印机源头厂家 |松普集团 | 风信子发稿-专注为企业提供全球新闻稿发布服务 | 大连海岛旅游网>>大连旅游,大连海岛游,旅游景点攻略,海岛旅游官网 | 真丝围巾|真丝丝巾|羊绒围巾|围巾品牌|浙江越缇围巾厂家定制 | 矿用履带式平板车|探水钻机|气动架柱式钻机|架柱式液压回转钻机|履带式钻机-启睿探水钻机厂家 | 首页|光催化反应器_平行反应仪_光化学反应仪-北京普林塞斯科技有限公司 | 防潮防水通风密闭门源头实力厂家 - 北京酷思帝克门窗 | 长沙一级消防工程公司_智能化弱电_机电安装_亮化工程专业施工承包_湖南公共安全工程有限公司 | 北京网站建设公司_北京网站制作公司_北京网站设计公司-北京爱品特网站建站公司 | 吉祥新世纪铝塑板_生产铝塑板厂家_铝塑板生产厂家_临沂市兴达铝塑装饰材料有限公司 | 伸缩器_伸缩接头_传力接头-巩义市润达管道设备制造有限公司 | 辽宁资质代办_辽宁建筑资质办理_辽宁建筑资质延期升级_辽宁中杭资质代办 | 不干胶标签-不干胶贴纸-不干胶标签定制-不干胶标签印刷厂-弗雷曼纸业(苏州)有限公司 | 超声波成孔成槽质量检测仪-压浆机-桥梁预应力智能张拉设备-上海硕冠检测设备有限公司 | 小型手持气象站-空气负氧离子监测站-多要素微气象传感器-山东天合环境科技有限公司 | 恒温振荡混匀器-微孔板振荡器厂家-多管涡旋混匀器厂家-合肥艾本森(www.17world.net) | 烟台条码打印机_烟台条码扫描器_烟台碳带_烟台数据采集终端_烟台斑马打印机-金鹏电子-金鹏电子 | 电销卡_稳定企业大语音卡-归属地可选-世纪通信 | 全温恒温摇床-水浴气浴恒温摇床-光照恒温培养摇床-常州金坛精达仪器制造有限公司 | 江苏大隆凯科技有限公司| 旗帜网络笔记-免费领取《旗帜网络笔记》电子书 | 定时排水阀/排气阀-仪表三通旋塞阀-直角式脉冲电磁阀-永嘉良科阀门有限公司 | 冷却塔风机厂家_静音冷却塔风机_冷却塔电机维修更换维修-广东特菱节能空调设备有限公司 | 盐水蒸发器,水洗盐设备,冷凝结晶切片机,转鼓切片机,絮凝剂加药系统-无锡瑞司恩机械有限公司 | 聚氨酯催化剂K15,延迟催化剂SA-1,叔胺延迟催化剂,DBU,二甲基哌嗪,催化剂TMR-2,-聚氨酯催化剂生产厂家 | 广州物流公司_广州货运公司_广州回程车运输 - 万信物流 | 机构创新组合设计实验台_液压实验台_气动实训台-戴育教仪厂 | 自进式锚杆-自钻式中空注浆锚杆-洛阳恒诺锚固锚杆生产厂家 | 心肺复苏模拟人|医学模型|急救护理模型|医学教学模型上海康人医学仪器设备有限公司 | 青海电动密集架_智能密集架_密集架价格-盛隆柜业青海档案密集架厂家 | 手板-手板模型-手板厂-手板加工-生产厂家,[东莞创域模型] | 氨水-液氨-工业氨水-氨水生产厂家-辽宁顺程化工 | 步入式高低温测试箱|海向仪器 | 健康管理师报考条件,考试时间,报名入口—首页 | 中天寰创-内蒙古钢结构厂家|门式刚架|钢结构桁架|钢结构框架|包头钢结构煤棚 | 优考试_免费在线考试系统_培训考试系统_题库系统_组卷答题系统_匡优考试 | 闭端端子|弹簧螺式接线头|防水接线头|插线式接线头|端子台|电源线扣+护线套|印刷电路板型端子台|金笔电子代理商-上海拓胜电气有限公司 | 口信网(kousing.com) - 行业资讯_行业展会_行业培训_行业资料 | 丁基胶边来料加工,医用活塞边角料加工,异戊二烯橡胶边来料加工-河北盛唐橡胶制品有限公司 |