【异常】JVM 获取 Linux 时间错误(相差12小时)

.

问题

有两台Linux机器:

date 命令查看时间相同

通过 date 命令查看时间,发现两台机器区域语言和时间都相同:

JVM获取系统时间相差12小时

通过最基本的java代码 new Date() 获得时间,发现两台机器的系统时间相差12小时。

其中一台输出的时区与上述date命令相同,都是东八区(CST,中国标准时间)。

另一台输出的时区与date命令不符,是西五区(EDT,美国东部白昼时间)。

根据理论经度,东八区 与 西五区 相差13小时。但因为时值美国夏令时,时刻的值被“人为”调整,所以两台机器相差12小时。

解决方法

可以确定那台 date命令所得时区与JVM所得时区不同的 机器时间是错的。

修复方法就是以正确的方式重新设置系统时区:

Shell代码

 

  1. ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime  

扩展

尽量自动化,减少对人肉运维的依赖

上述 date命令所得时区 与 JVM所得时区 不一致的问题,就是因为操作系统的时区未被正确设置。

这往往是不合格的“运维人员”“虎操作”导致的。

这种错误对于需要处理时间的Java应用而言是致命的!!!

不但无法得到正确的系统当前时间,也无法解析历史时间数据。 如,你之前在MySQL中正确存储了一个时间值,在这种错误的系统环境中,JVM解析这个来自数据库的行为也会出错。

此外,如果你的系统需要多台机上的Java应用基于各自的系统时间来合作完成某项业务,那么错误的那台机器会将你的业务逻辑完全破坏。

这种错误还非常难排查,你几乎不会去怀疑系统时区问题,因为date命令显示时区是正确的。

尽量使用维护成本低、准确无歧义的方式表示时间

不要使用时区缩写

时区缩写很可能有歧义。如,CST 可以表示:

  • 美国中部时间:Central Standard Time (USA)

  • 澳大利亚中部时间:Central Standard Time (Australia)

  • 中国标准时间:China Standard Time

  • 古巴标准时间:Cuba Standard Time

可以考虑用数值来表示时区。如,+08:00 表示东八区。

不要用夏令时

很多国家有 夏令时 和 冬令时 之分。在夏令时,时刻会被人为调整。

这种做法其实非常得不偿失,应尽量避免去涉及此类问题。

不要用年号纪年法

这也是一种“人祸”,非常浪费社会资源。

日本换个天皇就改个年号,平白浪费了很多社会资源。

这种纪年法展示的信息也与世界标准的公元纪年法格格不入,非常不利于信息交流。

很多非国际公认度量单位也对世界级的信息交流非常不友好,尽量不要使用。如,英尺、加仑、盎司。

CentOS7修改时区的正确姿势

Java TimeZone 和 Linux TimeZone问题

发布了219 篇原创文章 · 获赞 3 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/hchaoh/article/details/103906448