日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql数据库时间突然是12小时制_为什么存入mysql数据库中的timestamp,晚了13或14个小时...

發(fā)布時間:2023/12/4 数据库 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql数据库时间突然是12小时制_为什么存入mysql数据库中的timestamp,晚了13或14个小时... 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

#?為什么存入mysql數(shù)據(jù)庫中的timestamp,晚了13個小時

##?查看數(shù)據(jù)庫時區(qū)

```

show?variables?like?'%time_zone%';

select?@@global.system_time_zone;

select?@@global.time_zone;

可以得到默認(rèn)數(shù)據(jù)庫時區(qū):

system_time_zone?|?CST?|

time_zone?|?SYSTEM|

```

##?CST時區(qū):4個含義

>CST可以為如下4個不同的時區(qū)的縮寫:

>1,美國中部時間:Central?Standard?Time?(USA)?UT-6:00?,又美國從“3月11日”至“11月7日”實(shí)行夏令時,美國中部時間改為?UT-05:00

>2,澳大利亞中部時間:Central?Standard?Time?(Australia)?UT+9:30

>3,中國標(biāo)準(zhǔn)時間:China?Standard?Time?UT+8:00

>4,古巴標(biāo)準(zhǔn)時間:Cuba?Standard?Time?UT-4:00

>PS:即中國標(biāo)準(zhǔn)時間UT+8,和美國UT-5,中間相差13個小時

##?查看java程序運(yùn)行的本地時區(qū)

```

TimeZone.getDefault();//得到"Asia/Shanghai"

```

##?debug與源碼分析:

>1,測試發(fā)現(xiàn),客戶端到j(luò)ava程序端的時間戳是正確的,即通過mybatis寫入數(shù)據(jù)庫之前時間戳是正確的

>2,**從mybatis一路跟蹤:mybatis?SqlTimestampTypeHandler.setNonNullParameter()->mybatis?PreparedStatement.setTimestamp-》mysql-connector preparedStatement.setTimestamp()-》preparedStatement.setTimestampInternal()-》TimeUtil.changTimestamp(),通過計算本地時區(qū)和數(shù)據(jù)庫時區(qū)差值,得到數(shù)據(jù)的時間戳,再轉(zhuǎn)成SimpleDateFormat.format?yyyy-MM-dd?HH:mm:ss格式的時間戳日期字符串,寫入數(shù)據(jù)庫**

>3,問題:java運(yùn)行的本地時區(qū)是"Asia/Shanghai",那mysql-connector得到的數(shù)據(jù)庫時區(qū)是什么樣的?連接數(shù)據(jù)庫的時候,mysql-connector會獲取數(shù)據(jù)庫的時區(qū)信息,如上數(shù)據(jù)庫時區(qū)查詢,得到SYSTEM,CST

##?mysql-connector獲取數(shù)據(jù)庫時區(qū)

>1,CST?的時區(qū)是一個很混亂的時區(qū),在與?MySQL?協(xié)商會話時區(qū)時,Java?會誤以為是?CST?-0500,而非?CST?+0800

```

private?void?configureTimezone()?throws?SQLException?{

String?configuredTimeZoneOnServer?=?(String)?this.serverVariables

.get("timezone");

if?(configuredTimeZoneOnServer?==?null)?{

configuredTimeZoneOnServer?=?(String)?this.serverVariables

.get("time_zone");

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

configuredTimeZoneOnServer?=?(String)?this.serverVariables

.get("system_time_zone");//得到CST,mysql-connector以為的CST是美國的CST-5:00

}

}

...

}

```

>2,TimeZone.getTimeZone(canonicalTimezone)得到CST,mysql-connector以為的CST是美國的CST-5:00,{"CST",?"America/Chicago"}

>3,mysql-connector?ZoneInfoFile?class時區(qū)簡寫和時區(qū)對應(yīng)關(guān)系

```

{{"ACT",?"Australia/Darwin"},

{"AET",?"Australia/Sydney"},

{"AGT",?"America/Argentina/Buenos_Aires"},

{"ART",?"Africa/Cairo"},

{"AST",?"America/Anchorage"},

{"BET",?"America/Sao_Paulo"},

{"BST",?"Asia/Dhaka"},

{"CAT",?"Africa/Harare"},

{"CNT",?"America/St_Johns"},

{"CST",?"America/Chicago"},

{"CTT",?"Asia/Shanghai"},

{"EAT",?"Africa/Addis_Ababa"},

{"ECT",?"Europe/Paris"},

{"IET",?"America/Indiana/Indianapolis"},

{"IST",?"Asia/Kolkata"},

{"JST",?"Asia/Tokyo"},

{"MIT",?"Pacific/Apia"},

{"NET",?"Asia/Yerevan"},

{"NST",?"Pacific/Auckland"},

{"PLT",?"Asia/Karachi"},

{"PNT",?"America/Phoenix"},

{"PRT",?"America/Puerto_Rico"},

{"PST",?"America/Los_Angeles"},

{"SST",?"Pacific/Guadalcanal"},

{"VST",?"Asia/Ho_Chi_Minh"}};

```

##?如何解決

###?一,修改數(shù)據(jù)庫時區(qū)

```

set?global?time_zone?=?'+8:00';//設(shè)置全局時區(qū)為東八區(qū)

set?time_zone?=?'+8:00';?//

flush?privileges;//刷新權(quán)限使設(shè)置立即生效

```

###?二,添加jdbc參數(shù):serverTimezone=GMT%2B8

```

db?useUnicode=true&characterEncoding=UTF-8&useAffectedRows=true&useTimezone=true&serverTimezone=GMT%2B8

```

##?會有什么問題

>1,因為老數(shù)據(jù)是基于CST-5:00,得到的時間戳日期字符串(yyyy-MM-dd?HH:mm:ss.SSS),寫入數(shù)據(jù)庫中,改了數(shù)據(jù)庫時區(qū)或修改了JDBC的時區(qū)配置,會導(dǎo)致舊數(shù)據(jù)比以前慢13個小時

##?那舊數(shù)據(jù)怎么辦

>1,創(chuàng)建一個mybatis?TimstampTypehandler專門處理timestamp類型,將某個時間以前的時間戳加上13個小時的時間戳間隔,即可

```

@MappedJdbcTypes(JdbcType.TIMESTAMP)

@MappedTypes(Timestamp.class)

public?class?TimestampHandler?extends?SqlTimestampTypeHandler?{

@Override

public?void?setNonNullParameter(PreparedStatement?ps,?int?i,?Timestamp?parameter,?JdbcType?jdbcType)

throws?SQLException?{

ps.setTimestamp(i,?parameter);

}

@Override

public?Timestamp?getNullableResult(ResultSet?rs,?String?columnName)

throws?SQLException?{

//TimeZone?tz=TimeZone.getDefault();

//TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));

Timestamp?timestampTemp=rs.getTimestamp(columnName);

long?lt=timestampTemp.getTime();

long?timestampSplit=1590249600000L;//2020-05-24?00:00:00的毫秒時間戳

if(timestampSplit>lt){

Timestamp?timestamp=new?Timestamp(lt+13*60*60*1000);

return?timestamp;

}else{

return?timestampTemp;

}

}

@Override

public?Timestamp?getNullableResult(ResultSet?rs,?int?columnIndex)

throws?SQLException?{

TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));

Timestamp?timestampTemp=rs.getTimestamp(columnIndex);

long?lt=timestampTemp.getTime();

long?timestampSplit=1590249600000L;//2020-05-24?00:00:00的毫秒時間戳

if(timestampSplit>lt){

Timestamp?timestamp=new?Timestamp(lt+13*60*60*1000);

return?timestamp;

}else{

return?timestampTemp;

}

}

@Override

public?Timestamp?getNullableResult(CallableStatement?cs,?int?columnIndex)

throws?SQLException?{

TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));

Timestamp?timestampTemp=cs.getTimestamp(columnIndex);

long?lt=timestampTemp.getTime();

long?timestampSplit=1590249600000L;//2020-05-24?00:00:00的毫秒時間戳

if(timestampSplit>lt){

Timestamp?timestamp=new?Timestamp(lt+13*60*60*1000);

return?timestamp;

}else{

return?timestampTemp;

}

}

}

```

##?多人開發(fā),timestamp時間戳使用規(guī)約

>1,接口參數(shù)涉及時間,都用時間戳,精確到秒或毫秒,全項目統(tǒng)一

>2,時間戳參數(shù)直接入庫,不要在代碼層再做一次SimpleDateFormat.format?yyyy-MM-dd?HH:mm:ss.SSS轉(zhuǎn)換,這樣會附加本地時區(qū),導(dǎo)致時間戳失效,mysql?connector在入庫前對timestamp類型做了本地時區(qū)和數(shù)據(jù)庫時區(qū)差值計算的

總結(jié)

以上是生活随笔為你收集整理的mysql数据库时间突然是12小时制_为什么存入mysql数据库中的timestamp,晚了13或14个小时...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。