问题现象

Date字段在不同机器上序列化、反序列化,时间值出现半个小时的偏差。

然而使用date命令查看系统时间,两台机器上的时间是一致的,时区都是CST(中间标准时间)。

1
2
>> date
Sat Jun 9 13:49:21 CST 2018

而且/etc/sysconfig/clock文件内容也是一样的。

1
2
>> cat /etc/sysconfig/clock
ZONE="Asia/Shanghai"

解决方案

方法一

通过TimeZone.setDefault方法在Java代码中强制设置时区为东8区。

1
2
3
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
// or
TimeZone.setDefault(TimeZone.getTimeZone("GMT+8"));

方法二

在JVM启动参数中增加-Duser.timezone=Asia/Shanghai,或者为GMT+8

方法三

后来发现,是因为服务器上的/etc/localtime文件指向的是/usr/share/zoneinfo/Asia/Harbin,从而导致序列化Date时出现时区偏差。

Java通过/usr/share/zoneinfo/Asia/Harbin的文件名来确定时区,而系统命令date是通过文件内容来确定的,因此结果不同。

解决方法是

1
ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

此方法在CentOS 6.5系统上验证,这里不能使用cp命令将文件复制过来,否则Java程序可能会出问题。

方法四

DTO中使用字符串表示时间有关的时间值。

参考资料