【轉】Java 獲取操作系統時區


 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;
    }

  

轉自:https://blog.csdn.net/zhaoxj_2017/article/details/99676852

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM