`

Time zone

 
阅读更多

有个ticket是关于time zone的,在本地测总是ok的,但是在国外客户那边总是fail,原来就是在获取time zone的方法中,在不同的环境中,取得time zone是不一样的。

 

比如这个time zone是中国的,

TimeZone timeZone = TimeZone.getTimeZone("Asia/Shanghai");

Calendar cal = CalendarFactoryUtil.getCalendar(timeZone); 

cal .set(Calendar.MONTH, 5);

cal .set(Calendar.DATE, 12);

cal .set(Calendar.YEAR, 2013);

cal .set(Calendar.HOUR_OF_DAY, 10);

cal .set(Calendar.MINUTE, 0);

这个当前时间 cal 的timezone就是中国的。 GMT +8

 

但是 cal.getTime() 确不一定是取得是中国timezone的时间, 这得根据这段code运行的web 容器的jvm timezone来决定的。

比如jvm的timezone是"Europe Paris" GMT+1, 

cal.getTime()的值就是2013-5-12 3:00:00   (10 - 7)

 

jvm设置的timezone. 在bin目录下setenv.bat文件中,-Duser.timezone=, 如果不设,就默认是当前jvm机器系统的timezone。

 

TimeZoneUtil.getDefault() 取得portal timezone。

CalendarFactoryUtil.getCalendar().getTimeZone 取得的是jvm的timezone。

TimeZone.getDefault() 取得是 当前jvm的timezone,如果jvm没有设置,就是操作系统的time zone。

 

关键点就是你要知道这个获得timezone 是来自哪里。

 

那如何从源码知道方法是从什么地方获取time zone的呢? 且听下回分解。

 

源码分析1:

 

TimeZoneUtil.getDefault() -->

private TimeZone getDefault() {
		TimeZone timeZone = TimeZoneThreadLocal.getDefaultTimeZone();

		if (timeZone != null) {
			return timeZone;
		}

		return _timeZone;  // TimeZone.getTimeZone("UTC");
	}
-->
在Tomcat启动阶段初始化Company时:
LocaleThreadLocal.setDefaultLocale(company.getLocale());
// 可以看出,设置的是portal级别的time zone,所以TimeZoneUtil.getDefault取portal time zone.
TimeZoneThreadLocal.setDefaultTimeZone(company.getTimeZone()); 
 

 

 

在TimeZoneThreadLocal类中,用ThreadLocal来存放default time zone. 是因为在初始化多个Company时,

会有线程安全问题。

 

 

String[] webIds = PortalInstances.getWebIds();

for (String webId : webIds) {
     PortalInstances.initCompany(servletContext, webId);
}
 

 

 

 源码分析2:

为什么TimeZone.getDefault()获取的是jvm的timezone。

String zoneID = AccessController.doPrivileged(new GetPropertyAction("user.timezone"));

 可以看到是从jvm的启动参数user.timezone 来获取的。

if (zoneID == null || zoneID.equals("")) {  //如果,jvm中没有设置timezone参数
	String country = AccessController.doPrivileged(
			new GetPropertyAction("user.country"));
	String javaHome = AccessController.doPrivileged(
			new GetPropertyAction("java.home"));
	try {
		zoneID = getSystemTimeZoneID(javaHome, country);//它就会取操作系统的timezone
		if (zoneID == null) {
			zoneID = GMT_ID; // 如果还是获取不到,就默认是GMT timezone
		}
	} catch (NullPointerException e) {
		zoneID = GMT_ID;
	}
}

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics