引子:(转载请注明出处)
今天测试人员向我报了个诡异的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,是否用了夏时令,现在是否在夏时令的范围内。

本文介绍了一种解决客户端与服务器端因夏令时导致的时区偏差问题的方法。通过客户端和服务器端的双重调整,确保了时区信息的一致性和准确性。
432

被折叠的 条评论
为什么被折叠?



