关于客户端与服务端时区不同导致客户端上的时间不准问题的解决方案

一、问题重现

随着企业向国际化方向发现,软件也不到不断向国际化发展。像软件实现多语言方案等等。但是服务端与客户端不在同一时区里,就会导致客户端上时间可能不准确,比如客户端要下载一份服务器上日志,日志上会有时间,就无法提供准备时间,因为用户一般都会以自己所在的时区上时间来看日志,但是日志却以服务端上时区显示时间。

二、问题分析

1、用户需要也是能够使用用户所在时区的时间。

2、服务端写日志一定以服务端上的时区或者以0时区来写入日志。

3、这样就用户下载后日志上的时间就不是以用户的时区为时间的基准了,即时间不准确。

三、解决方案

总方案是客户端在下载前先告诉服务端要以什么时区进入写入日志,然后服务端就以该时区作为基准对日志上的时间做一定修改。

四、代码实现

1、客户端的代码实现

1.1  以C++技术开发的,获取时间区的方式与代码:

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"数值是分钟,如果是东八区,这里表示"-480"。
1.2  以Javascript技术开发,获取时区的方式与代码:
var curDateTime = new Date();
var nTimezone = curDateTime.getTimezoneOffset(); 
g_fTimezone = (-nTimezone) / 60;            //同上
网页客户端如果使用“2014-10-10T12:20:20+08:00”这样格式的字符串进入客户端与服务端通信。

1.2.1  服务端若上述格式发送网页客户端,那网页客户端要将其转换成客户端所在时区的时间。像火狐等浏览器可以直接通过Date类转换,但是IE浏览器却无法直接转换。那就必须使用其他方案将其转换。(考虑浏览器的兼容性,这里使用下面的方法)其Javascript代码如下:

 var nSplitTime = strDate.indexOf("T");     //注: 这里的strDate就是上述格式的时间串  “2014-10-10T12:20:20+08:00”
 var bEastTimezone = true;
 var nSplitZone = strDate.indexOf("+");//这里看一下是东区还是西区的
 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;//算出服务端与客户端的时区差
 
 dateNewTime = dateNewTime.setTime(dateNewTime.getTime() + (nTimezoneDiff * 60 * 1000));
 
 var reDate = new Date(dateNewTime);//"reDate"表示最终在客户端展示的时间 
1.2.2  客户端要以此格式的时间向服务端发送,这里就对时区显示“+08:00”的格式做一定解析。Javascript代码如下:

   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;
    }
   }
   if(nDiffMinute >= 10){
    g_strTimezone = g_strTimezone + ":" + nDiffMinute;
   }else{
    g_strTimezone = g_strTimezone + ":0" + nDiffMinute;
   }
2、服务端实现

2.1  服务端如果使用python技术实现,这里主要是客户端下载服务端的日志文件的解析。从上述方案上可以知道,这里需要客户端将它所在时区上传到服务端,服务端才将日志中的时间修改成该时区的时间。python代码实现如下:

tm = datetime.utcfromtimestamp(tmpTime)   //注:tmpTime 表示日志中所记录的时间差
tm = tm + timedelta(hours=fTimeZone) //注:fTimeZone 就是客户端传过来的时区信息  比如“东八区”—>“+8.0" ,"西九点五区"——>"-9.5"。
服务端暂时先考虑这个,其他后续再补。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值