服务器时间正确,Java程序时区不对问题解决

文章描述了在两台服务器上遇到的Java默认时区问题,通过分析JDK获取时区的流程,发现错误服务器的时区文件被篡改。解决方法是使用`timedatectlset-timezoneAsia/Shanghai`和创建相应/etc/timezone文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

服务器执行date命令显示时间正确
执行timedatectl status命令结果如下:
在这里插入图片描述
看起来是Time zone没有设置好,但是登录另外一台正常的服务器,执行timedatectl status也是一样的

直接写一个简单的Java程序TestTimeZone.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获取默认时区的流程:

  1. 读取系统属性user.timezone(VM options)
  2. 读取环境变量 TZ 的值
  3. 读取文件/etc/timezone的值
  4. 查找 /etc/localtime文件,如果文件/etc/localtime是软链接,则直接读取软链的路径和文件名作为时区
  5. 如果文件/etc/localtime不是软链接而是一个普通文件,则去/usr/share/zoneinfo目录下读取时区文件,进行内容匹配,匹配到内容一致的文件名作为时区
  6. 如果都找不到,则以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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值