一、问题描述
日期字符串1990-6-16转java的Date对象,落库(mysql)后,DB日期显示减少一天(1990-6-15)
二、原因
根本原因:java使用的时区与数据库使用的时区不匹配
1. 1990-6-16处于中国实行夏令时期间
2. 字符串转Date,SimpleDateFormat#parse,jvm默认时区=Asia/Shanghai,会处理夏令时,可以看到CDT夏令时标识
3. db时区=CST,中国标准时区(可以视作东八区时区)
4. 落库时,CDT转CST,时间减一小时,导致日期减一
三、解决办法
SimpleDateFormat#parse时,将时区设置成GMT+8(不会对夏令时处理),字符串1990-6-17转Date后的时间是1990-6-17 01:00:00(相当于CST 1990-6-17 00:00:00),落库后,正常显示为1990-6-17
三、补充
1. CDT和CST
CDT:中国夏令时
CST:CST可以同时表示美国、澳大利亚、中国、古巴四个国家的标准时间,在中国表示 中国标准时
Central Standard Time USA UT-6:00
Central Standard Time Australia UT+9:30
China Standard Time UT+8:00
Cuba Standard Time UT-4:00
2. Asia/Shanghai和GMT+8
Asia/Shanghai:中国本地时间(会因为当地政策做特殊处理,例如夏令时),会处理中国夏令时
GMT+8:东八区时间(多个国家可能处在这个时区,统一使用该时区的时间规则,不受各国政策影响),不会处理中国夏令时
3. 夏令时介绍:http://www.cwtea.net/article/9228.html
4. 中国夏令时实行时间区间
四、拓展
有个小小的疑问,如果从db取出时,将数据按照相同规则进行反向转换,是不是就可以得到与输入时一致的结果了。
测试,精度到日期的时间类型,是的。
db为datetime和timestamp,从数据库取出,cst ——> cdt,时间加一小时,正常转换
db字段是date,不可以,因为java Date转数据库date,减去一个小时,带来的影响是,日期-1(1990-06-17 ——> 1990-06-16);数据库date到java Date时,只加一个小时,取出来后1990-06-16 01:00:00