一、問題重現(xiàn)
創(chuàng)新互聯(lián)公司自2013年起,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都網(wǎng)站建設(shè)、成都做網(wǎng)站網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢想脫穎而出為使命,1280元石柱土家族做網(wǎng)站,已為上家服務(wù),為石柱土家族各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:18982081108
隨著企業(yè)向國際化方向發(fā)現(xiàn),軟件也不到不斷向國際化發(fā)展。像軟件實(shí)現(xiàn)多語言方案等等。但是服務(wù)端與客戶端不在同一時(shí)區(qū)里,就會(huì)導(dǎo)致客戶端上時(shí)間可能不準(zhǔn)確,比如客戶端要下載一份服務(wù)器上日志,日志上會(huì)有時(shí)間,就無法提供準(zhǔn)備時(shí)間,因?yàn)橛脩粢话愣紩?huì)以自己所在的時(shí)區(qū)上時(shí)間來看日志,但是日志卻以服務(wù)端上時(shí)區(qū)顯示時(shí)間。
二、問題分析
1、用戶需要也是能夠使用用戶所在時(shí)區(qū)的時(shí)間。
2、服務(wù)端寫日志一定以服務(wù)端上的時(shí)區(qū)或者以0時(shí)區(qū)來寫入日志。
3、這樣就用戶下載后日志上的時(shí)間就不是以用戶的時(shí)區(qū)為時(shí)間的基準(zhǔn)了,即時(shí)間不準(zhǔn)確。
三、解決方案
總方案是客戶端在下載前先告訴服務(wù)端要以什么時(shí)區(qū)進(jìn)入寫入日志,然后服務(wù)端就以該時(shí)區(qū)作為基準(zhǔn)對日志上的時(shí)間做一定修改。
四、代碼實(shí)現(xiàn)
1、客戶端的代碼實(shí)現(xiàn)
1.1 以C++技術(shù)開發(fā)的,獲取時(shí)間區(qū)的方式與代碼:
[cpp] view plaincopy
TIME_ZONE_INFORMATION tziOld;
DWORD dwRet;
dwRet = GetTimeZoneInformation(&tziOld); //該方法是C++自帶API
if (dwRet == TIME_ZONE_ID_INVALID)
{
LOGT( Log_Error ) << "Get Timezone faile";
}
float fTimezone = (-tziOld.Bias) / 60;//該"tziOld.Bias"數(shù)值是分鐘,如果是東八區(qū),這里表示"-480"。
1.2 以Javascript技術(shù)開發(fā),獲取時(shí)區(qū)的方式與代碼:
[javascript] view plaincopy
var curDateTime = new Date();
var nTimezone = curDateTime.getTimezoneOffset();
g_fTimezone = (-nTimezone) / 60; //同上
網(wǎng)頁客戶端如果使用“2014-10-10T12:20:20+08:00”這樣格式的字符串進(jìn)入客戶端與服務(wù)端通信。
1.2.1 服務(wù)端若上述格式發(fā)送網(wǎng)頁客戶端,那網(wǎng)頁客戶端要將其轉(zhuǎn)換成客戶端所在時(shí)區(qū)的時(shí)間。像火狐等瀏覽器可以直接通過Date類轉(zhuǎn)換,但是IE瀏覽器卻無法直接轉(zhuǎn)換。那就必須使用其他方案將其轉(zhuǎn)換。(考慮瀏覽器的兼容性,這里使用下面的方法)其Javascript代碼如下:
[javascript] view plaincopy
var nSplitTime = strDate.indexOf("T"); //注: 這里的strDate就是上述格式的時(shí)間串 “2014-10-10T12:20:20+08:00”
var bEastTimezone = true;
var nSplitZone = strDate.indexOf("+");//這里看一下是東區(qū)還是西區(qū)的
if(nSplitZone == -1){
bEastTimezone = false;
nSplitZone = strDate.indexOf("-");
}
var strDateTemp = strDate.slice(0, nSplitTime);
var strTimeTemp = strDate.slice(nSplitTime + 1, nSplitZone);
var strTimeZoneTemp = strDate.slice(nSplitZone + 1);
var arrayDate = strDateTemp.split("-");
var arrayTime = strTimeTemp.split(":");
var arrayZone = strTimeZoneTemp.split(":");
var nTimeZoneOffset = parseInt(arrayZone[0],10)*60 + parseInt(arrayZone[1],10);
if(!bEastTimezone){
nTimeZone = -nTimeZone;
}
var dateNewTime = new Date(parseInt(arrayDate[0],10), parseInt(arrayDate[1],10)-1,
parseInt(arrayDate[2],10), parseInt(arrayTime[0],10),
parseInt(arrayTime[1],10), parseInt(arrayTime[2],10));
var nTimezoneDiff = (-dateNewTime.getTimezoneOffset()) - nTimeZoneOffset;//算出服務(wù)端與客戶端的時(shí)區(qū)差
dateNewTime = dateNewTime.setTime(dateNewTime.getTime() + (nTimezoneDiff * 60 * 1000));
var reDate = new Date(dateNewTime);//“reDate"表示最終在客戶端展示的時(shí)間
1.2.2 客戶端要以此格式的時(shí)間向服務(wù)端發(fā)送,這里就對時(shí)區(qū)顯示“+08:00”的格式做一定解析。Javascript代碼如下:
[javascript] view plaincopy
var curDateTime = new Date();
var nTimezone = curDateTime.getTimezoneOffset();
var nDiffMinute = nTimezone % 60;
var nDiffHour = (nTimezone - nDiffMinute) / 60;
nDiffMinute = Math.abs(nDiffMinute);
nDiffHour = Math.abs(nDiffHour);
if(nTimezone<0){
if(nDiffHour >= 10){
g_strTimezone = "+" + nDiffHour;
}else{
g_strTimezone = "+0" + nDiffHour;
}
}else {
if(nDiffHour >= 10){
g_strTimezone = "-" + nDiffHour;
}else {
g_strTimezone = "-0" + nDiffHour;
}
}
[javascript] view plaincopy
if(nDiffMinute >= 10){
g_strTimezone = g_strTimezone + ":" + nDiffMinute;
}else{
g_strTimezone = g_strTimezone + ":0" + nDiffMinute;
}
2、服務(wù)端實(shí)現(xiàn)
2.1 服務(wù)端如果使用python技術(shù)實(shí)現(xiàn),這里主要是客戶端下載服務(wù)端的日志文件的解析。從上述方案上可以知道,這里需要客戶端將它所在時(shí)區(qū)上傳到服務(wù)端,服務(wù)端才將日志中的時(shí)間修改成該時(shí)區(qū)的時(shí)間。python代碼實(shí)現(xiàn)如下:
[python] view plaincopy
tm = datetime.utcfromtimestamp(tmpTime) //注:tmpTime 表示日志中所記錄的時(shí)間差
tm = tm + timedelta(hours=fTimeZone) //注:fTimeZone 就是客戶端傳過來的時(shí)區(qū)信息 比如“東八區(qū)”—>“+8.0" ,"西九點(diǎn)五區(qū)"——>"-9.5"。
服務(wù)端暫時(shí)先考慮這個(gè),其他后續(xù)再補(bǔ)。