# 为什么存入mysql数据库中的timestamp,晚了13个小时

## 查看数据库时区

```

show variables like '%time_zone%';

select @@global.system_time_zone;

select @@global.time_zone;

可以得到默认数据库时区:

system_time_zone | CST |

time_zone | SYSTEM|

```

## CST时区:4个含义

>CST可以为如下4个不同的时区的缩写:

>1,美国中部时间:Central Standard Time (USA) UT-6:00 ,又美国从“3月11日”至“11月7日”实行夏令时,美国中部时间改为 UT-05:00

>2,澳大利亚中部时间:Central Standard Time (Australia) UT+9:30

>3,中国标准时间:China Standard Time UT+8:00

>4,古巴标准时间:Cuba Standard Time UT-4:00

>PS:即中国标准时间UT+8,和美国UT-5,中间相差13个小时

## 查看java程序运行的本地时区

```

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

```

## debug与源码分析:

>1,测试发现,客户端到java程序端的时间戳是正确的,即通过mybatis写入数据库之前时间戳是正确的

>2,**从mybatis一路跟踪:mybatis SqlTimestampTypeHandler.setNonNullParameter()->mybatis PreparedStatement.setTimestamp-》mysql-connector preparedStatement.setTimestamp()-》preparedStatement.setTimestampInternal()-》TimeUtil.changTimestamp(),通过计算本地时区和数据库时区差值,得到数据的时间戳,再转成SimpleDateFormat.format yyyy-MM-dd HH:mm:ss格式的时间戳日期字符串,写入数据库**

>3,问题:java运行的本地时区是"Asia/Shanghai",那mysql-connector得到的数据库时区是什么样的?连接数据库的时候,mysql-connector会获取数据库的时区信息,如上数据库时区查询,得到SYSTEM,CST

## mysql-connector获取数据库时区

>1,CST 的时区是一个很混乱的时区,在与 MySQL 协商会话时区时,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时区简写和时区对应关系

```

{{"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"}};

```

## 如何解决

### 一,修改数据库时区

```

set global time_zone = '+8:00';//设置全局时区为东八区

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

flush privileges;//刷新权限使设置立即生效

```

### 二,添加jdbc参数:serverTimezone=GMT%2B8

```

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

```

## 会有什么问题

>1,因为老数据是基于CST-5:00,得到的时间戳日期字符串(yyyy-MM-dd HH:mm:ss.SSS),写入数据库中,改了数据库时区或修改了JDBC的时区配置,会导致旧数据比以前慢13个小时

## 那旧数据怎么办

>1,创建一个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;

}

}

}

```

## 多人开发,timestamp时间戳使用规约

>1,接口参数涉及时间,都用时间戳,精确到秒或毫秒,全项目统一

>2,时间戳参数直接入库,不要在代码层再做一次SimpleDateFormat.format yyyy-MM-dd HH:mm:ss.SSS转换,这样会附加本地时区,导致时间戳失效,mysql connector在入库前对timestamp类型做了本地时区和数据库时区差值计算的

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

  1. mysql时间戳13小时_为什么存入mysql数据库中的timestamp,晚了13或14个小时

    为什么存入mysql数据库中的timestamp,晚了13或14个小时 使用markdown,方便大家浏览,就又更新了一下 查看数据库时区 show variables like '%time_zon ...

  2. mysql 当前时间小时制_日期函数——MYSQL

    目录 1,日期时间格式化 date_format,  time_format 2,计算日期.时间之间的差值,单位有秒,天,月 3,字符串转换为日期函数str_to_date( )函数 4,timest ...

  3. mysql的时间在cmd的输入格式_获取“System.FormatException:输入字符串的格式不正确。”在日期时间对象插入到MySql数据库...

    我正在使用C#与Mvvm Light和Mysql数据库的应用程序.当我做一个插入到数据库与对象是一个DateTime对象,我收到以下错误的参数:获取"System.FormatExcepti ...

  4. mysql 设置 0、1 用什么数据类型_什么是MySQL数据库?看这一篇干货文章就够了!...

    前言 为啥学习MySQL呢?因为MySQL是最流行的关系型数据库管理系统之一,在web应用方面,MySQL是最好的软件.MySQL所使用的sql语言是用于访问数据库的最常用标准化语言. 这篇文章,我会 ...

  5. 数据模拟:利用Java模拟数据(姓名,邮箱,地址,电话等信息,时间,工资,1-10随机数)并存入mysql

    学大数据分析的同学们在做数据分析时一般很难找到适合数据集,本文就来分享一下如何利用Java模拟数据,并将产生数据保存至mysql数据库中. 主要技术就是Java产生数据,利用mybatis存入mysq ...

  6. mysql数据库任务驱动式教程课后答案_正版二手 MySQL数据库任务驱动式教程 石坤泉 汤双霞 王鸿铭 人民邮电出版社 9787115362711...

    商品描述: 温馨提示:亲!旧书库存变动比较快,有时难免会有断货的情况,为保证您的利益,拍前请务必联系卖家咨询库存情况!谢谢!书名:MySQL数据库任务驱动式教程 编号:3428270 ISBN:978 ...

  7. mysql获取当天每小时统计_详解mysql 获取某个时间段每一天、每一个小时的统计数据...

    获取每一天的统计数据 做项目的时候需要统对项目日志做分析,其中有一个需求是获取某个给定的时间段内,每一天的日志数据,比如说要获取从2018-02-02 09:18:36到2018-03-05 23:1 ...

  8. mysql 查看表v空间自增涨_专业解决 MySQL 查询速度慢与性能差!

    一.什么影响了数据库查询速度 1.1 影响数据库查询速度的四个因素 1.2 风险分析 QPS:Queries Per Second意思是"每秒查询率",是一台服务器每秒能够相应的查 ...

  9. mysql 查看表v空间自增涨_分分钟解决MySQL查询速度慢与性能差

    阅读本文大概需要 6 分钟. 一.什么影响了数据库查询速度 1.1 影响数据库查询速度的四个因素 1.2 风险分析 QPS: QueriesPerSecond意思是"每秒查询率", ...

最新文章

  1. modifiers在JAVA中_Java Modifier.classModifiers方法代碼示例
  2. Object-c学习之路三(@class与#import的区别)
  3. MSP430F5529 DriverLib 库函数学习笔记(四)UART通信
  4. 重定位----操作系统做的事情
  5. 【以太坊源码阅读】椭圆曲线加密和EIP155
  6. SolidWorks Simulation热仿真优化设计 提高企业生产效率
  7. 心知天气html,esp8266初级入门实用教程一之访问心知天气读取实时天气数据
  8. matlab残差的计算,请教MATLAB中拟合圆或者椭圆的残差如何计算
  9. 微信小程序:经典语录大全微信小程序源码
  10. 将实际环节都拆成了理论公式后,做好抽奖活动其实不难!
  11. android one a2,小米第二代 Android One 机种小米 A2 与平价版小米 A2 Lite 于西班牙发表...
  12. 推荐系统实践(八)UCG 利用ltf-idf方法
  13. linux(debian 11)下安装nginx
  14. 如何看待互联网公司 996 现象,是种什么样的体验?
  15. 红帽rhel系统 find命令详解
  16. adventure项目 可视化看板总结
  17. 留个念想,clipper库的使用效果
  18. [2023最新]美少妇Metasploit(MSF)下载安装及使用详解,永久免费使用,环境配置和使用技巧指南
  19. Typec转HDMI 4K30HZ扩展芯片方案CS5261和CS5266设计参数及电路对比
  20. flash游戏右键功能

热门文章

  1. asp.net core监控—引入Prometheus(五)
  2. 从TimeSpan说起
  3. 祝贺王远当选为中国区第二位 Teams MVP
  4. 【春华秋实】.NET Core之只是多看了你一眼
  5. ASPNET Core 2.x中的Kestrel服务器
  6. ASP.NET Core之跨平台的实时性能监控
  7. SQL Server 急救包(First Responder Kit)入门教程
  8. 在Linux开发.NET——拜拜了Win10
  9. 玩玩Xamarin Evolve 2016带来的新特性(一)-iOS Simulator(for Windows)
  10. 最新版dotnet-cli下的ASP.NET Core和asp.net mvc【RC2尝鲜】