1.问题来源
测试的同事反馈说APP海外版本的时间与实际时间少了8个小时。于是开始排查问题,最后发现问题出在getTime()函数上。
数据库里存储的数据是Date类型,我将Date类型通过getTime()方法转换为时间戳返回给APP显示。服务运行在Docker上,通过Rancher部署。在打镜像的时候,我在Dockerfile文件里指定了时区:
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
我指定的时区是上海(东八区),而我的服务是部署在亚马逊北美云服务器上的。getTime()方法与时区有关系,它会根据Docker容器指定的时区来生成时间戳。这样会导致海外APP在显示时间时少8个小时。
2.误解
误以为getTime()与时区无关,误解产生的原因是getTime()方法的注释:
/**
* Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT
* represented by this <tt>Date</tt> object.
*
* @return the number of milliseconds since January 1, 1970, 00:00:00 GMT
* represented by this date.
*/
public long getTime() {
return getTimeImpl();
}
实际上getTime()与程序真实运行的容器(服务器)所在的时区相关。如果程序运行在东八区,它返回北京时间1970年01月01日08时00分00秒起至现在东八区时间的总毫秒数。如果运行在UTC时区则返回1970年01月01日00时00分00秒起至当前UTC时间的总毫秒数。