TimeZone構造の注意点、およびno dsvのソリューション

2209 ワード

引用子:(転載は出典を明記してください)
今日テストスタッフは私に奇妙なバグを報告した.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)は1つずつマッチングします.
 
上の2つのステップではdaylight savingの誤差が発生します.
 
サーバ側のソリューション:
jdkによれば
1.GMT+(-)xxのようなTimeZoneを作成する場合、dsvの問題は考慮されません.
2.getRawOffsetは常にDsvを含まない値を返します.
 
では、クライアントのoffsetを受信すると
offset/-60だけでGMT+xxのxxが得られます.
 
クライアントのソリューション:
 
夏の季節は永遠に1時間前に放送されるからだ.必要なのは
 
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を取得し、サマータイムが使用されているか、現在サマータイムの範囲内にあるかを確認できます.