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


    服务器执行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());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    编译&运行:
    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]
    
    • 1
    • 2
    • 3
    • 4
    • 5

    阅读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

  • 相关阅读:
    Jekyll 选项(options)和子命令(subcommand)小手册
    如何从 FastReport VCL 中将报表导出为PNG格式?
    在3分钟内使用AI-Chat生成精美PPT(附AI工具)
    使用JMeter的JSON提取器:通过递归下降查找,从接口响应中提取特定字段
    SQL语句中对时间字段进行区间查询
    电子表电路
    Mybiosource丨Mybiosource兔抗人磷脂酶 A2 多克隆抗体
    (Note)中文EI检索期刊目录
    小程序主题随接口而变
    Docker基础篇
  • 原文地址:https://blog.csdn.net/li281037846/article/details/132801844