Java 获取操作系统时区

Java中的Timezone类获取的时区是JVM初始化时的设置,而非操作系统实际时区。当操作系统时区改变,JVM不会自动更新。为获取操作系统当前时区,需要调用Timezone的本地方法getSystemTimeZoneID,以确保获取最新时区信息。

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

       Java 可以通过 Timezone 获取时区,但是通过 Timezone 获取的时区是 JVM 初始化时保存的时区,并不是操作系统所设置的时区。当修改过操作系统的时区后,JVM 并不会同步更新。Timezone 获取时区的代码如下:

// 获取 JVM 启动时获取的时区
TimeZone.getDefault();

// 获取任意指定区域的时区
String[] zoneIDs = TimeZone.getAvailableIDs();
for(String zoneID: zoneIDs) {
    TimeZone.getTimeZone(zoneID);    
}

       当修改了操作系统的时区后,但JVM 并不会同步更新,因此直接通过 Timezone 获取默认时区并不是修改后的时区。若要程序获取修改后的操作系统时区,则可以这样修改:

// 将获取默认时区的两个前置条件设置为 false, 令其获取系统时间,原理见后面分析
synchronized (TimeZone.class) {
    TimeZone.setDefault(null);
    System.setProperty("user.timezone", "");

    TimeZone.getDefault();
}

这么做的原因是,我们需要调用Timezone 的本地方法 getSystemTimeZoneID(String javaHome),请看源码

    /**
     * Returns the reference to the default TimeZone object. This
     * method doesn't create a clone.
     */
    static TimeZone getDefaultRef() {
        TimeZone defaultZone = defaultTimeZone;
        if (defaultZone == null) {
            // Need to initialize the default time zone.
            defaultZone = setDefaultZone();
            assert defaultZone != null;
        }
        // Don't clone here.
        return defaultZone;
    }

    private static synchronized TimeZone setDefaultZone() {
        TimeZone tz;
        // get the time zone ID from the system properties
        String zoneID = AccessController.doPrivileged(
                new GetPropertyAction("user.timezone"));

        // if the time zone ID is not set (yet), perform the
        // platform to Java time zone ID mapping.
        if (zoneID == null || zoneID.isEmpty()) {
            String javaHome = AccessController.doPrivileged(
                    new GetPropertyAction("java.home"));
            try {
                zoneID = getSystemTimeZoneID(javaHome);    // 重点,这个方法就是我们需要调用的,但是 Timezone 并没有对外提供接口访问该方法,因此只能将前置条件改为 false, 令程序调用该方法即可获取操作系统的时间。
                if (zoneID == null) {
                    zoneID = GMT_ID;
                }
            } catch (NullPointerException e) {
                zoneID = GMT_ID;
            }
        }

        // Get the time zone for zoneID. But not fall back to
        // "GMT" here.
        tz = getTimeZone(zoneID, false);

        if (tz == null) {
            // If the given zone ID is unknown in Java, try to
            // get the GMT-offset-based time zone ID,
            // a.k.a. custom time zone ID (e.g., "GMT-08:00").
            String gmtOffsetID = getSystemGMTOffsetID();
            if (gmtOffsetID != null) {
                zoneID = gmtOffsetID;
            }
            tz = getTimeZone(zoneID, true);
        }
        assert tz != null;

        final String id = zoneID;
        AccessController.doPrivileged(new PrivilegedAction<Void>() {
            @Override
                public Void run() {
                    System.setProperty("user.timezone", id);
                    return null;
                }
            });

        defaultTimeZone = tz;
        return tz;
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值