服务器执行date命令显示时间正确
执行timedatectl status命令结果如下:
看起来是Time zone没有设置好,但是登录另外一台正常的服务器,执行timedatectl status也是一样的
直接写一个简单的Java程序TestTimeZone.java:
Java
import java.util.TimeZone;
public class TestTimeZone{
public static void main(String[] args) {
System.out.println(TimeZone.getDefault());
}
}
编译&运行:
javac TestTimeZone.java
java TestTimeZone
分别在两台服务器上运行,对比结果:
//错误时区
sun.util.calendar.ZoneInfo[id="GMT",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]
//正确时区
sun.util.calendar.ZoneInfo[id="Asia/Chungking",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null]
阅读JDK源码,大致整理了一下Java获取默认时区的流程:
- 读取系统属性user.timezone(VM options)
- 读取环境变量 TZ 的值
- 读取文件/etc/timezone的值
- 查找 /etc/localtime文件,如果文件/etc/localtime是软链接,则直接读取软链的路径和文件名作为时区
- 如果文件/etc/localtime不是软链接而是一个普通文件,则去/usr/share/zoneinfo目录下读取时区文件,进行内容匹配,匹配到内容一致的文件名作为时区
- 如果都找不到,则以GMT作为默认时区
检查两台服务器进行验证,可以确定user.timezone和TZ都是没有设置的,然后/etc/timezone文件也没有,排除掉前3个
查看/etc/localtime文件,不是软链接,是一个普通文件
对 /etc/localtime进行查看:
先查看时区正确的机器,对比/etc/localtime文件和/usr/share/zoneinfo/Asia/Chungking文件,内容是相同的
再查看时区错误的机器,/etc/localtime文件内容和时区正确的机器相同,但是/usr/share/zoneinfo/Asia/Chungking文件内容不知为何被修改了
至此已经定位到原因,实际上即使时区正确的机器,时区设置也不太合理
解决问题的办法很多,可以通过把/etc/localtime软链到时区文件解决
我这里直接采用timedatectl set-timezone Asia/Shanghai命令的方式(实际也是通过软链的方式)
保险起见同时创建/etc/timezone文件,并设置内容为:Asia/Shanghai