java 获取系统的时区_【转】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() {

@Override

public Void run() {

System.setProperty("user.timezone", id);

return null;

}

});

defaultTimeZone = tz;

return tz;

}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值