mysql之關(guān)于CST和GMT時(shí)區(qū)時(shí)間轉(zhuǎn)換方式
問(wèn)題
今天在往數(shù)據(jù)庫(kù)查詢一條數(shù)據(jù)時(shí)突然發(fā)現(xiàn)插入的時(shí)間竟然比系統(tǒng)時(shí)間少了13個(gè)小時(shí)。。。
然后因?yàn)椴迦霑r(shí)間的問(wèn)題延伸出之前寫的SQL中只要涉及到創(chuàng)建時(shí)間都有可能存在,也就是某月1號(hào)插入的數(shù)據(jù),你在統(tǒng)計(jì)時(shí),當(dāng)月并未統(tǒng)計(jì),實(shí)際上是在上個(gè)月的統(tǒng)計(jì)數(shù)據(jù)中。。。。
這就尷尬了。。。
排查
1、首先查證測(cè)試環(huán)境數(shù)據(jù)庫(kù)時(shí)區(qū):
SHOW VARIABLES LIKE ‘%time_zone%'
竟然設(shè)置的CST時(shí)區(qū),之前不是啊,之后詢問(wèn)主管才得知,當(dāng)前改造的老項(xiàng)目生產(chǎn)環(huán)境的數(shù)據(jù)庫(kù)使用的CST。。。
為了保證測(cè)試一致性,就修改了數(shù)據(jù)庫(kù)時(shí)區(qū)。。。
到此,直接找到時(shí)間相差13個(gè)小時(shí)的原因。。。。
解決
既然知道時(shí)間差,也知道時(shí)區(qū)了,那么問(wèn)題就好解決了,
mysql中有一個(gè)函數(shù)CONVERT_TZ() 可以解決這個(gè)問(wèn)題(這里為了更直觀,直接貼圖)
通過(guò)這條SQL查詢出來(lái)的時(shí)間
SELECT report_id,create_time FROM report_item WHERE report_id=2584
結(jié)果:
上圖中的時(shí)間就是CST時(shí)區(qū)時(shí)間,單實(shí)際上系統(tǒng)時(shí)間是:2021-05-21 10:05:12,相差足足13個(gè)小時(shí)
所以SQL修改為:
SELECT report_id,CONVERT_TZ(create_time, 'UTC','+13:00') as create_time FROM report_item WHERE report_id=2584
到這里,基本完美解決了時(shí)區(qū)轉(zhuǎn)換問(wèn)題,后來(lái)度娘了一下這個(gè)問(wèn)題,發(fā)現(xiàn)CST和GMT時(shí)間相差是13或14小時(shí),至于是13小時(shí)還是14小時(shí),取決于你傳遞給數(shù)據(jù)庫(kù)的時(shí)間
函數(shù)介紹:CONVERT_TZ(dt,from_tz,to_tz)
轉(zhuǎn)換datetime值dt,從 from_tz 由給定轉(zhuǎn)到 to_tz 時(shí)區(qū)給出的時(shí)區(qū),并返回的結(jié)果值。
如果參數(shù)無(wú)效該函數(shù)返回NULL。
示例
yyyy-MM-dd格式
SELECT CONVERT_TZ('2021-5-21 15:30:00','UTC','+13:00') AS 北京時(shí)間;
這里注意一點(diǎn),我的SQL時(shí)區(qū)是CST,但是我在這里用的UTC來(lái)作為標(biāo)準(zhǔn)時(shí)間,所以可以理解CST-UTC-GMT,所以最后我用了+13:00,這里也可能會(huì)有人問(wèn)為什么不直接用CST來(lái)轉(zhuǎn),這個(gè)嘛。。。
可能是我mysql版本問(wèn)題?
我直接寫CST,竟然返回給我一個(gè)null。。。尷尬。。。
使用這樣的寫法可以解決現(xiàn)在的問(wèn)題,但是最重要的一點(diǎn)就是從根源上去解決,不要去給數(shù)據(jù)庫(kù)設(shè)置默認(rèn)時(shí)區(qū),如果一定要,那設(shè)置GMT或者UTC都可以,不用使用CST時(shí)區(qū),因?yàn)檫@個(gè)時(shí)區(qū)存在很多很多的問(wèn)題,這里就不意義贅述了。。。
大家可以去找度娘要關(guān)于CST時(shí)區(qū)的問(wèn)題
總結(jié)
1、數(shù)據(jù)庫(kù)時(shí)區(qū)最好不要設(shè)置成CST,以免出現(xiàn)上面的錯(cuò)誤
2、當(dāng)數(shù)據(jù)庫(kù)中的時(shí)間用的是時(shí)間類型時(shí)候,Java中可以用String,但是這種做法不是很國(guó)際化
3、在數(shù)據(jù)庫(kù)連接字符串中設(shè)置時(shí)區(qū)。
推薦這種方式,如下:
jdbc:mysql://xxxx:3306/table_name?serverTimezone=Asia/ShanghaiallowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- mysql8.0?my.ini?如何永久修改時(shí)區(qū)
- 解決MySQL時(shí)區(qū)日期時(shí)差8個(gè)小時(shí)的問(wèn)題
- MySQL timestamp與時(shí)區(qū)問(wèn)題的解決
- MySQL修改時(shí)區(qū)的方法圖文詳解
- MySQL中的時(shí)區(qū)設(shè)置方式
- 關(guān)于mysql的時(shí)區(qū)問(wèn)題
- MySQL時(shí)區(qū)差8小時(shí)的多種問(wèn)題解決方法
- Mysql查看數(shù)據(jù)庫(kù)時(shí)區(qū)并設(shè)置時(shí)區(qū)的方法
- IDEA連接mysql時(shí)區(qū)問(wèn)題解決
- Java與MySQL導(dǎo)致的時(shí)間不一致問(wèn)題分析
相關(guān)文章
MySQL?SQL預(yù)處理(Prepared)的語(yǔ)法實(shí)例與注意事項(xiàng)
所謂預(yù)編譯語(yǔ)句就是將此類SQL語(yǔ)句中的值用占位符替代,可以視為將 SQL語(yǔ)句模板化或者說(shuō)參數(shù)化,一般稱這類語(yǔ)句叫Prepared Statements,下面這篇文章主要給大家介紹了關(guān)于MySQL?SQL預(yù)處理(Prepared)的相關(guān)資料,需要的朋友可以參考下2022-01-01MySQL報(bào)錯(cuò)1067 :Invalid default value for&n
在使用MySQL5.7時(shí),還原數(shù)據(jù)庫(kù)的時(shí)候報(bào)錯(cuò),下面就來(lái)介紹一下MySQL報(bào)錯(cuò)1067 :Invalid default value for ‘字段名’,具有一定的參考價(jià)值,感興趣的可以了解一下2024-05-05MySQL的savepoint簡(jiǎn)介及實(shí)例
MySQL中的保存點(diǎn)Savepoint是一個(gè)用于控制事務(wù)的重要工具,本文主要介紹了MySQL的savepoint簡(jiǎn)介及實(shí)例,具有一定的參考價(jià)值,感興趣的可以了解一下2023-08-08MySQL安裝提示配置信息已損壞請(qǐng)聯(lián)系技術(shù)人員
為了重新安裝MySql,看別人的博客說(shuō)在注冊(cè)表中搜索mysql,全部刪除。再安裝時(shí)提示配置信息已損壞,遇到這個(gè)問(wèn)題怎么處理呢,下面小編給大家?guī)?lái)了詳細(xì)解決方法,感興趣的朋友一起看看吧2023-01-01