mysql版本升级导致的时区问题 您所在的位置:网站首页 european的缩写 mysql版本升级导致的时区问题

mysql版本升级导致的时区问题

2023-06-10 20:02| 来源: 网络整理| 查看: 265

背景 公司各个项目组用的mysql 版本不一样,有的是5.x稳定守旧版,有的最近喜欢用8.x高级迎新版,结果出了问题。

现象,数据库中保存的时间与java读取的时间字段不一样。

最开始数据库mysql版本为5.7.28,驱动为5.1 反正5.x都没什么问题。

数据库时区为 show variables like '%zone%'

现在有人使用mysql 8.x的版本,项目中就使用8.x的驱动

 导致的问题就是时间字段不一致!!而且读取的时候还出问题了。

Caused by: com.mysql.cj.exceptions.WrongArgumentException: HOUR_OF_DAY: 2 -> 3

举例 数据库为5.x版本,数据库存放数据

我使用5.x的驱动

            mysql         mysql-connector-java         5.1.49    

得到结果:id=8637200,last_update_date2021-03-13 14:03:54.0

使用8.x的驱动

            mysql         mysql-connector-java         8.0.16    

得到结果:id=8637200,last_update_date2021-03-14 04:03:54.0

相差时间有10个小时,其中有同事遇到过相差13个小时的,这种肯定就是时区问题了

java.sql.SQLException: HOUR_OF_DAY: 2 -> 3_-兰天白云-的博客-CSDN博客

 解决办法分为几种

 1. mysql-connector-java.jar版本6.x、8.x降级为5.1.x  2. 对于高版本jdbc,连接串强制指定时区参数:serverTimezone=GMT%2B8

     这个第二点有人说serverTimezone=Asia/Shanghai。  3. 对于高版本jdbc,mysql数据库强制修改time_zone为“+8:00”,而非“SYSTEM

第一点 经过之前测试降级没有问题。我用5.1的驱动连接没问题。

第二点 那种才是正确的呢?

serverTimezone=Asia/Shanghai 的结果是正确的

id=8637200,last_update_date2021-03-13 14:03:54.0

serverTimezone=GMT%2B8 的结果也是正确的。

id=8637200,last_update_date2021-03-13 14:03:54.0

怪我经验太少 都是中国的。。但是一个是shanghai一个是2B8。。。差的太多了

//北京时间东八区 serverTimezone=GMT%2B8  //上海时间 serverTimezone=Asia/Shanghai

下面我来好好学习下时区,以及为什么会出现这个问题。 

 先学习下时区的基本信息UTC GMT EST CST 区别_cst est_天已青色等烟雨来的博客-CSDN博客

GMT - (Greenwich Mean Time)的缩写,指的是皇家格林威治天文台的标准时间,称作格林威治时间,因为本初子午线通过此地区,因此也称为世界标准时间。然而地球的自转不是完全规律的,而且正逐渐减慢,因此自1924年开始,格林威治时间(GMT)已经不再被视为标准时间,取而代之的是"世界协调时间" (UTC: Coordinated Universal Time)UTC - 协调世界时(Coordinated Universal Time)是最主要的世界时间标准,其以原子时秒长为基础,在时刻上尽量接近于格林尼治标准时间。UTC 是一个标准,而不是一个时区CST - 北京时间,China Standard Time,中国标准时间,是中国的标准时间。在时区划分上,属东八区,比协调世界时早8小时,记为UTC+8EST - 和CST一样,是众多时区中的一种时区。 缩写全称中文名称类型UTC 偏移量+03+03-UTC +03:00+04+04-UTC +04:00+05+05-UTC +05:00+0530+0530-UTC +05:30+06+06-UTC +06:00ACDTAustralian Central Daylight Time澳大利亚中部夏令时夏令时UTC +10:30ACSTAustralian Central Standard Time澳大利亚中部标准时间-UTC +09:30ACTAcre Time阿卡时间-UTC -05:00ACWSTAustralian Central Western Standard Time澳大利亚中西部标准时间-UTC +08:45ADTAtlantic Daylight Time大西洋夏令时间夏令时UTC -03:00AEDTAustralian Eastern Daylight Time澳大利亚东部夏令时夏令时UTC +11:00AESTAustralian Eastern Standard Time澳大利亚东部标准时间-UTC +10:00AFTAfghanistan Time阿富汗时间-UTC +04:30AKDTAlaska Daylight Time阿拉斯加夏令时夏令时UTC -08:00AKSTAlaska Standard Time阿拉斯加标准时间-UTC -09:00AMSTAmazon Summer Time亚马逊夏令时夏令时UTC -03:00AMTAmazon Time亚马逊时间-UTC -04:00ARTArgentina Time阿根廷时间-UTC -03:00ASTArabia Standard Time阿拉伯标准时间-UTC +03:00ASTAtlantic Standard Time大西洋标准时间-UTC -04:00AWSTAustralian Western Standard Time澳大利亚西部标准时间-UTC +08:00AZOSTAzores Summer Time亚速尔群岛夏令时夏令时UTC -00:00AZOTAzores Time亚速尔群岛时间-UTC -01:00BOTBolivia Time玻利维亚时间-UTC -04:00BRSTBrasília Summer Time巴西利亚夏令时夏令时UTC -02:00BRTBrasília Time巴西利亚时间-UTC -03:00BSTBritish Summer Time英国夏令时间夏令时UTC +01:00BTTBhutan Time不丹时间-UTC +06:00CATCentral Africa Time中非时间-UTC +02:00CDTCentral Daylight Time中部夏令时间夏令时UTC -05:00CDTCuba Daylight Time古巴夏令时夏令时UTC -04:00CESTCentral European Summer Time欧洲中部夏令时间夏令时UTC +02:00CETCentral European Time欧洲中部时间-UTC +01:00CHADTChatham Island Daylight Time查塔姆岛夏令时夏令时UTC +13:45CHASTChatham Island Standard Time查塔姆岛标准时间-UTC +12:45CHOSTChoibalsan Summer Time乔巴山夏令时夏令时UTC +09:00CHOTChoibalsan Time乔巴山时间-UTC +08:00CHUTChuuk Time丘克时间-UTC +10:00CKTCook Island Time库克群岛时间-UTC -10:00CLSTChile Summer Time智利夏令时夏令时UTC -03:00CLTChile Standard Time智利标准时间-UTC -04:00CSTCentral Standard Time中部标准时间-UTC -06:00CSTChina Standard Time中国标准时间-UTC +08:00CSTCuba Standard Time古巴标准时间-UTC -05:00ChSTChamorro Standard Time查莫罗标准时间-UTC +10:00EASSTEaster Island Summer Time复活岛夏令时夏令时UTC -05:00EASTEaster Island Standard Time复活节岛标准时间-UTC -06:00EATEastern Africa Time非洲东部时间-UTC +03:00ECTEcuador Time厄瓜多尔时间-UTC -05:00EDTEastern Daylight Time东部夏令时间夏令时UTC -04:00EESTEastern European Summer Time东欧夏令时夏令时UTC +03:00EETEastern European Time东欧时间-UTC +02:00ESTEastern Standard Time东部标准时间-UTC -05:00FKSTFalkland Islands Summer Time福克兰群岛夏令时-UTC -03:00GFTFrench Guiana Time法属圭亚那时间-UTC -03:00GILTGilbert Island Time吉尔伯特群岛时间-UTC +12:00GMTGreenwich Mean Time格林威治标准时间-UTC -00:00GSTGulf Standard Time海湾标准时间-UTC +04:00HKTHong Kong Time香港时间-UTC +08:00HSTHawaii Standard Time夏威夷标准时间-UTC -10:00ICTIndochina Time印度支那时间-UTC +07:00IDTIsrael Daylight Time以色列夏令时夏令时UTC +03:00IRDTIran Daylight Time伊朗夏令时夏令时UTC +04:30IRSTIran Standard Time伊朗标准时间-UTC +03:30ISTIndia Standard Time印度标准时间-UTC +05:30ISTIrish Standard Time爱尔兰标准时间夏令时UTC +01:00ISTIsrael Standard Time以色列标准时间-UTC +02:00JSTJapan Standard Time日本标准时间-UTC +09:00KOSTKosrae Time科斯雷时间-UTC +11:00KSTKorea Standard Time韩国标准时间-UTC +08:30LINTLine Islands Time莱恩群岛时间-UTC +14:00MDTMountain Daylight Time山区夏令时夏令时UTC -06:00MHTMarshall Islands Time马绍尔群岛时间-UTC +12:00MSKMoscow Standard Time莫斯科标准时间-UTC +03:00MSTMountain Standard Time山地标准时间-UTC -07:00MYTMalaysia Time马来西亚时间-UTC +08:00NDTNewfoundland Daylight Time纽芬兰夏令时夏令时UTC -02:30NPTNepal Time尼泊尔时间-UTC +05:45NSTNewfoundland Standard Time纽芬兰标准时间-UTC -03:30NUTNiue Time纽埃时间-UTC -11:00NZDTNew Zealand Daylight Time新西兰夏令时夏令时UTC +13:00NZSTNew Zealand Standard Time新西兰标准时间-UTC +12:00PDTPacific Daylight Time太平洋夏令时夏令时UTC -07:00PETPeru Time秘鲁时间-UTC -05:00PGTPapua New Guinea Time巴布亚新几内亚时间-UTC +10:00PHTPhilippine Time菲律宾时间-UTC +08:00PKTPakistan Standard Time巴基斯坦标准时间-UTC +05:00PONTPohnpei Standard Time波纳佩标准时间-UTC +11:00PSTPacific Standard Time太平洋标准时间-UTC -08:00SASTSouth Africa Standard Time南非标准时间-UTC +02:00SBTSolomon Islands Time所罗门群岛时间-UTC +11:00SGTSingapore Time新加坡时间-UTC +08:00SRTSuriname Time苏里南时间-UTC -03:00SSTSamoa Standard Time萨摩亚标准时间-UTC -11:00TAHTTahiti Time塔希提岛时间-UTC -10:00TLTEast Timor Time东帝汶时间-UTC +09:00TVTTuvalu Time图瓦卢时间-UTC +12:00ULASTUlaanbaatar Summer Time乌兰巴托夏令时夏令时UTC +09:00ULATUlaanbaatar Time乌兰巴托时间-UTC +08:00UYSTUruguay Summer Time乌拉圭夏令时夏令时UTC -02:00UYTUruguay Time乌拉圭时间-UTC -03:00VETVenezuelan Standard Time委内瑞拉标准时间-UTC -04:00WASTWest Africa Summer Time西非夏令时夏令时UTC +02:00WATWest Africa Time西非时间-UTC +01:00WESTWestern European Summer Time西欧夏令时间夏令时UTC +01:00WETWestern European Time西欧时间-UTC -00:00WIBWestern Indonesian Time印尼西部时间-UTC +07:00WITEastern Indonesian Time印度尼西亚东部时间-UTC +09:00WITACentral Indonesian Time印度尼西亚中部时间-UTC +08:00

 注意这里上面的有三个CST!!

说下时区的注意点。

在中国新疆哈密是东六区到北京是东八区,从西到东有2个小时的时差,

在美国从东向西分别为东部时间(EST)(西五区时间)、中部时间(CST)(西六区时间)、山地时间(MST)(西七区时间)、太平洋时间(西部时间)(PST)(西八区时间)、阿拉斯加时间(AKST)(西九区时间)和夏威夷时间(HST)(西十区时间)

但是这个时差在中国为啥不明显,因为在中国这个时间统一了,比如北京八点上班,此时按照时区时间新疆是6点,时间也差不了太多,所以可以看作中国无时差,无时区。

但是在美国不一样,时差由政府把握,也即是我们说的每到一个时区,你需要把手表时间快或慢一小时。

再补充学习下夏令时的概念。

夏令时_百度百科

注意对于夏令时各个国家也有不同的做法。

中国1992年起,夏令时暂停实行。

俄罗斯自从2011年3月27日开始永久使用夏令时,把时间拨快一小时,不再调回。

美国夏时制的实行与否,完全由各州、各县自行决定,不由联邦政府统一规定。目前美国绝大部分地区实行夏令时。

此时举个例子,

我们现在是东八区,美国华盛顿是西五区,此时时差应该是(东8-西5-中时区)=13个小时

因为有夏令时的存在,华盛顿西五区要快1小时,变成了西四区,所以现在的时差如下=12小时

此时回头看下我们数据 2021-03-13 14:03:54.0和2021-03-14 04:03:54.0 相差了10个小时好像和12/13对不上?接着学习。

夏令时: 由于美国有夏令时,CST非夏令时对应 UTC-06:00,夏令时对应 UTC-05:00 。 美国的夏令时,从每年3月第2个星期天凌晨开始,到每年11月第1个星期天凌晨结束。 以2020年为例: 3月第2个星期天为3月8号

夏令时开始时间调整前:2020年03月08日星期日 02:00:00,时间向前拨一小时. 调整后:2020年03月08日星期日 03:00:00

夏令时结束时间调整前:2020年11月01日星期日 02:00:00,时间往回拨一小时. 调整后:2020年11月01日星期日 01:00:00

这意味这:CST没有2020-03-08 02:00:00~2020-03-08 03:00:00 这个区间的时间。会有两个 2020-11-01 01:00:00~2020-11-01 02:00:00区间的时间

说实话这里我都有点乱了。

public static void main(String[] args) { Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("CST"), Locale.US); calendar.setLenient(false);//容错模式 例如分钟1000会进位到小时 //2020-03-08 01:02:00 calendar.set(2020, 2, 8, 1, 2, 0); Date date1 = new Date(calendar.getTimeInMillis()); String format = f1.format(date1); System.out.println("设置时间为 2020-03-08 01:02:00," + "CST时区时间为 " + format); //2020-03-08 01:02:00 非夏令时间,于北京时间相差14小时。 //2020-03-08 03:02:00 calendar.set(2020, 2, 8, 3, 2, 0); Date date3 = new Date(calendar.getTimeInMillis()); String format3 = f1.format(date3); System.out.println("设置时间为 2020-03-08 03:02:00," + "CST时区时间为 " + format3); //2020-03-08 03:02:00 夏令时间,于北京时间相差13小时。 //抛出 Exception: HOUR_OF_DAY: 2 -> 3 //2020-03-08 02:02:00 calendar.set(2020, 2, 8, 2, 2, 0); //抛出异常:java.lang.IllegalArgumentException: HOUR_OF_DAY: 2 -> 3 Date error = new Date(calendar.getTimeInMillis()); String format2 = f1.format(error); System.out.println("设置时间为 2020-03-08 03:02:00," + "CST时区时间为 " + format2); }

设置时间为 2020-03-08 01:02:00,CST时区时间为 2020-03-08 15:02:00 设置时间为 2020-03-08 03:02:00,CST时区时间为 2020-03-08 16:02:00 Exception in thread "main" java.lang.IllegalArgumentException: HOUR_OF_DAY: 2 -> 3     at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:2829)     at java.util.Calendar.updateTime(Calendar.java:3393)     at java.util.Calendar.getTimeInMillis(Calendar.java:1782)     at com.chenchi.learning.java.calender.CalenderTest.main(CalenderTest.java:66)

 这里有个问题 我在中国默认的timeZone为 Asia/Shanghai。

上面设置的CST是啥?

美国中部时间 Central Standard Time (USA) UTC-05:00 / UTC-06:00 澳大利亚中部时间 Central Standard Time (Australia) UTC+09:30 --这个上面又是 ACST 中国标准时间 China Standard Time UTC+08:00 古巴标准时间 Cuba Standard Time UTC-04:00

我他妈也是服了,每个人说的不一样,不过按照结果来说 java代码里应该是美国的UTC-5/6,注意本来是CST的 因为现在是夏天所以又是CDT。

此时有点晕了 理一理。

UTC=GMT 可以理解吧 

GMT: 格林威治标准时间,英国伦敦格林威治定为 0° 经线开始的地方,地球每 15° 经度 被分为一个时区,共分为 24 个时区,相邻时区相差一小时。

UTC:世界协调时间,经严谨计算得到的时间,精确到秒,误差在 0.9s 以内, 是比 GMT 更为精确的世界时间。

东八区就是中国标准时间,它也是相对 GMT 而言的。所以,我们平时碰到相差 8 小时问题,就是因为中国标准时间和 GTM 相差 8 个时区,也就是相差 8 小时。 

再来看 CST,百度百科里说 CST可视为中国、古巴的标准时间或美国、澳大利亚的中部时间,

这他m的一个CST代表四个不同的时区,怎么代表?

我们说的

美国本土横跨西五区至西八区,共四个时区,每个时区对应一个标准时间。从东向西分别为东部时间(EST)(西五区时间)、中部时间(CST)(西六区时间)、山地时间(MST)(西七区时间)、太平洋时间(西部时间)(PST)(西八区时间)。

又因为夏令时的存在CST!=GMT-6。

搞不动了。。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有