TimeZone构造注意点,及no dsv的解决方案

引子:(转载请注明出处

今天测试人员向我报了个诡异的bug。在local跑程序的时候 webbrowser的time zone经过服务器端解析后,可以正确的得到GMT+8(Beijing),但是,一旦放到服务器上,跑出来的结果就变成了GMT+7。

开始百思不得其解,后来想想,会不会是夏令时(daylight saving time)引发的问题。

系统将client timezone转换为server 的TimeZone的流程:

1.new Date().getTimezoneOffset()取得browser的offset,并提交

2.服务器端接收到,并转换

int rawOffset = new Date().getTimezoneOffset() * (-1) * 60 * 1000

然后用TimeZone.getTimeZone(TimeZone.availableID)一个个去匹配。

上面两步都会产生daylight saving的误差。

服务器端的解决方案:

根据jdk上所说

1.如果是GMT+(-)xx这种去创建TimeZone,则不会考虑dsv的问题。

2.getRawOffset始终返回不含Dsv的值。

那么,在接收到客户端的offset后

只要offset / -60就可以得到GMT+xx的xx。

客户端的解决方案:

由于夏时令永远是往前播一个小时之类的。所以只需要:

var clientTimeZone = getTimeZone();

alert(clientTimeZone.displayName);
alert(clientTimeZone.useDaylightTime);
alert(clientTimeZone.inDayLightTime);

function getTimeZone() {
	
	var date = new Date();
	
	var offset = date.getTimezoneOffset();

	date.setDate(1);
	
	var dayLightTime = false;
	
	var inDayLightTime = false;
	
	for (var month = 0; month < 12; month++) {
		
		date.setMonth(month);
		
		var currentMonthOffset = date.getTimezoneOffset();
		
		if (offset != currentMonthOffset) {
			
			dayLightTime = true;
			
			if (offset < currentMonthOffset) {
				offset = currentMonthOffset;
				inDayLightTime = true;
			}
		}
	}
	
	var dispName = "GMT";
	var offsetHour = offset / -60;
	
	if (offsetHour >= 0) {
		dispName += "+";
	}
	
	dispName += offsetHour;
	
	
	return {
		// 时区名
		displayName: dispName,
		
		// 和标准的偏移时间
		rawOffset: offset,
		
		// 是否用了夏时令
		useDaylightTime: dayLightTime,
		
		// 是否在夏时令的范围内
		inDayLightTime: inDayLightTime
	};
	
}
 

即可取得时区名,和标准UTC的offset,是否用了夏时令,现在是否在夏时令的范围内。

猜你喜欢

转载自rainsilence.iteye.com/blog/1470873