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時間前に放送されるからだ.必要なのは
タイムゾーン名と標準UTCのoffsetを取得し、サマータイムが使用されているか、現在サマータイムの範囲内にあるかを確認できます.
今日テストスタッフは私に奇妙なバグを報告した.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を取得し、サマータイムが使用されているか、現在サマータイムの範囲内にあるかを確認できます.