Java同一条数据,两个时间,两个时区问题;CDT和CST的坑
项目场景:Oracle同步数据到Mysql
- 从Oracle进行视图查询,进行数据同步,把数据全量同步到Mysql中。
问题描述:时间丢失一天
问题:某个字段(时间类型)查询的时候,写入的时候,数据都是正确的,但是,插入Mysql时间就少了一天。
Java代码—Mapper SQL:
<select id="selectMyByPage" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List"/>
FROM SYSADM.PS_STAFF_BASE_INFO
WHERE emplid = #{emplid,jdbcType=VARCHAR}
</select>
Java代码—代码:
public void selectMyByPage() {
List<StaffBaseInfo> staffBaseInfos = oracleStaffBaseInfoDao.selectMyByPage("10001122");
staffBaseInfos.forEach(item -> {
System.out.println("生日: " + item.getBirthdate() + ", 入职日期" + item.getStartDtChn());
});
int insertBatch = staffBaseInfoDao.insertBatch(staffBaseInfos);
System.out.println("插入结果: " + insertBatch);
}
Java代码—代码SQL日志显示:
生日: Sun Aug 21 00:00:00 CDT 1988, 入职日期Wed Jul 13 00:00:00 CST 2011
Preparing: INSERT INTO staff_base_info ( emplid,birthdate,start_dt_chn, orig_hire_dt) VALUES ( ?, ?, ?)
Parameters: (10001122(String), 1988-08-21 00:00:00.0(Timestamp), 2011-07-13 00:00:00.0(Timestamp)
Updates: 1
Java代码—对数据库的数据影响:
emplid 生日 入职日期
10001122 1988-08-20 2011-07-13
Java代码—数据库link配置:
jdbc:mysql://ip:port/XXX?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8 # 这里配置了GMT+8
上诉代码和日志已经写清楚了,从Oracle中查询和插入Mysql的过程。以及数据的展示。
原因分析:
- 是否因为Oracle时区设置存在的有问题。导致,获取到的时间错误。
- 是否因为Mysql中没有设置时区。
- 是否因为从Oracle中读取数据时候,提供的Oracle视图处理的有问题。
解决方案:
- 查看问题真正产生的原因。
1. 打印获取到日期,发现两个日期存在了时区的不同,一个为CDT,一个为CST;
2. CDT:为夏令时时间(中华人民共和国在1986年~1991年实行了夏令时制度,每年夏令时实行时间如下:
1986年5月4日至9月14日(1986年因是实行夏令时的第一年,从5月4日开始到9月14日结束)
1987年4月12日至9月13日,
1988年4月10日至9月11日,
1989年4月16日至9月17日,
1990年4月15日至9月16日,
1991年4月14日至9月15日。
);CST:为美国、澳大利亚、古巴或中国的标准时间。
3. CST的时间和CDT的时间是相差了13个小时。 - 解决方案:
- 常用的CMT+8的时区设置,并不兼容夏令时。
- 而使用TimeZone = Asia/Shanghai,则会兼容夏令时。
- 当mysql的url,修改为配置serverTimezone=Asia/Shanghai;解决了插入数据库时间错误问题。
- 但是,当返回给前端的时候,设置JsonFormat的timeZone的时候,也需要使用此配置:@JsonFormat(timezone = “Asia/Shanghai”, pattern = “yyyy/MM/dd”);这样才可以保证前端的数据展示正确。
.