UTC转换本地时间

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

//=====================================================================
//TITLE:
//    UTC转换本地时间
//AUTHOR:
//    norains
//DATE:
//    Friday 26- March-2010
//Environment:
//     WINDOWS XP
//     WINDOWS CE
//=====================================================================


     一般情况下,我们很少需要用到UTC转换为本地时间--因为如果仅仅是获取本机的本地时间,我们完全可以不用如此麻烦,直接调用GetLocalTime即可。

 

  即使万一真的需要用到UTC转换到特定时区的本地时间,只要你是在WinXP的环境下,也并不会花费太大的劲,只要调用SystemTimeToTzSpecificLocalTime函数:
  

  1. SYSTEMTIME sysTime = {0};  
  2.   
  3. //获取系统时间。和GetLocalTime不同,该函数返回的为UTC时间  
  4. GetSystemTime(&sysTime);  
  5.   
  6. //中国时区的信息  
  7. TIME_ZONE_INFORMATION DEFAULT_TIME_ZONE_INFORMATION = {-480};  
  8.   
  9. //将UTC时间转换为中国时区的本地时间  
  10. SystemTimeToTzSpecificLocalTime(&DEFAULT_TIME_ZONE_INFORMATION,&sysTime,&sysTime);  
     SYSTEMTIME sysTime = {0};          //获取系统时间。和GetLocalTime不同,该函数返回的为UTC时间     GetSystemTime(&sysTime);          //中国时区的信息     TIME_ZONE_INFORMATION DEFAULT_TIME_ZONE_INFORMATION = {-480};          //将UTC时间转换为中国时区的本地时间     SystemTimeToTzSpecificLocalTime(&DEFAULT_TIME_ZONE_INFORMATION,&sysTime,&sysTime);    


  就这么简单,调用一个函数即可进行转换。可能大家唯一疑惑的是DEFAULT_TIME_ZONE_INFORMATION的取值是怎么来的,其实很简单,TIME_ZONE_INFORMATION的时差是以分钟为单位的,北京时差为8个小时,所以8*60=480。如果是别的时区,可以依此进行更改。
  
  WinXP是简单了,但对于WinCE却是麻烦了。相对于WinXP来说,需要用到时区转换的机会更多,因为很多系统定制时,习惯于定义系统的默认语言为英文,以此加快加载速度和减小系统容量,所以在显示时间时必须要进行一次UTC的时间转换。可这更常使用的场合,却偏偏没有SystemTimeToTzSpecificLocalTime函数!
  
  没辙,活人总不能被尿给憋死吧?微软不为我们准备,那我们就自己丰衣足食咯!
  
  我们先从原理上想想这时区的转换,其实无非就是UTC时间偏移多少个小时,也就一个简简单单的加加减减。但问题在于,SYSTEMTIME是一个结构体,成员有秒、分、时等等。如果只是时间上的加减倒还是简单,毕竟都是60进制的;但涉及到日期,却不是一般的麻烦了。比如是今天是1号,那前一天是几号?这个不仅涉及到大小月,还有闰月的问题。不仅如此,还需要判断当前是星期几,这也不是一件轻松的事情。所以,直接采用SYSTEMTIME进行计算,对于我们来说是不太现实。
  
  那我们换个角度来想,SYSTEMTIME不方便,那么我们转换为FILETIME来计算不就可以了么?FILETIME可是以100个亿分之一秒为单位的啊,这不就可以直接加减了么?话虽如此,但还是有个问题。我们来看看FILETIME的声明:

  1. typedef struct _FILETIME {   
  2.   DWORD dwLowDateTime;   
  3.   DWORD dwHighDateTime;   
  4. } FILETIME;  
  typedef struct _FILETIME {     DWORD dwLowDateTime;     DWORD dwHighDateTime;   } FILETIME;
  
  问题就来了,FILETIME是一个结构体,包含了两个成员,我们无法直接进行算术运算!
  
  别急,问题还不是很严重。仔细观察一下,FILETIME是由两个DWORD组成,每个DWORD是32bit,一共64bit。那么,我们直接用一个64bit的变量存储该数值,不就可以简单地进行运算了?
  
  所以,我们WinCE下自力更生的SystemTimeToTzSpecificLocalTime函数出炉了:
  1.     
  2. BOOLSystemTimeToTzSpecificLocalTime(LPTIME_ZONE_INFORMATION lpTimeZone,LPSYSTEMTIME lpUniversalTime,LPSYSTEMTIME lpLocalTime)  
  3. {  
  4.  if(lpTimeZone == NULL || lpUniversalTime == NULL || lpLocalTime == NULL)  
  5.  {  
  6.   //如果指针为空,则没有必要进行任何计算  
  7.   return FALSE;  
  8.  }  
  9.   
  10.  //将UTC时间由SYSTEMTIME转换为FILETIME格式  
  11.  FILETIME ftUniversalTime = {0};  
  12.  SystemTimeToFileTime(lpUniversalTime,&ftUniversalTime);  
  13.   
  14.  //将FILETIME格式时间的数值存储到一个DWORD64变量中  
  15.  DWORD64 ddwUniversalTime = ftUniversalTime.dwHighDateTime;  
  16.  ddwUniversalTime = ddwUniversalTime << 32;  
  17.  ddwUniversalTime += ftUniversalTime.dwLowDateTime;  
  18.   
  19.   
  20.  //因为FILETIME的时间单位是100个亿分之一秒,然后TIME_ZONE_INFORMATION的时间单位是分,所以这里需要乘以600000000   
  21.  DWORD64 ddwBias = abs(lpTimeZone->Bias);   
  22.  ddwBias *= 600000000;  
  23.   
  24.   
  25.  //转换公式为:LOCAL_TIME = UTC - BIAS  
  26.  DWORD64 ddwLocalTime = 0;  
  27.  if(lpTimeZone->Bias > 0)  
  28.  {    
  29.   ddwLocalTime = ddwUniversalTime - ddwBias;  
  30.  }  
  31.  else if(lpTimeZone->Bias < 0)  
  32.  {  
  33.   ddwLocalTime = ddwUniversalTime + ddwBias;  
  34.  }  
  35.   
  36.    
  37.  //将DWORD64数值转换为FILETIME格式  
  38.  FILETIME ftLocalTime = {0};  
  39.  ftLocalTime.dwLowDateTime = static_cast<DWORD>(ddwLocalTime);  
  40.  ftLocalTime.dwHighDateTime = static_cast<DWORD>(ddwLocalTime >> 32);  
  41.     
  42.  //将FILETIME数值转换为SYSTEMTIME格式并返回  
  43.  return FileTimeToSystemTime(&ftLocalTime,lpLocalTime);  
  44.   
  45.   
  46.      }  
  BOOLSystemTimeToTzSpecificLocalTime(LPTIME_ZONE_INFORMATION lpTimeZone,LPSYSTEMTIME lpUniversalTime,LPSYSTEMTIME lpLocalTime){ if(lpTimeZone == NULL || lpUniversalTime == NULL || lpLocalTime == NULL) {  //如果指针为空,则没有必要进行任何计算  return FALSE; } //将UTC时间由SYSTEMTIME转换为FILETIME格式 FILETIME ftUniversalTime = {0}; SystemTimeToFileTime(lpUniversalTime,&ftUniversalTime); //将FILETIME格式时间的数值存储到一个DWORD64变量中 DWORD64 ddwUniversalTime = ftUniversalTime.dwHighDateTime; ddwUniversalTime = ddwUniversalTime << 32; ddwUniversalTime += ftUniversalTime.dwLowDateTime; //因为FILETIME的时间单位是100个亿分之一秒,然后TIME_ZONE_INFORMATION的时间单位是分,所以这里需要乘以600000000  DWORD64 ddwBias = abs(lpTimeZone->Bias);  ddwBias *= 600000000; //转换公式为:LOCAL_TIME = UTC - BIAS DWORD64 ddwLocalTime = 0; if(lpTimeZone->Bias > 0) {    ddwLocalTime = ddwUniversalTime - ddwBias; } else if(lpTimeZone->Bias < 0) {  ddwLocalTime = ddwUniversalTime + ddwBias; }  //将DWORD64数值转换为FILETIME格式 FILETIME ftLocalTime = {0}; ftLocalTime.dwLowDateTime = static_cast<DWORD>(ddwLocalTime); ftLocalTime.dwHighDateTime = static_cast<DWORD>(ddwLocalTime >> 32);   //将FILETIME数值转换为SYSTEMTIME格式并返回 return FileTimeToSystemTime(&ftLocalTime,lpLocalTime);     }
  
  因为该函数的接口和WinXP的一模一样,所以文章开头的代码,我们可以不用做任何更改就能正确地在WinCE中运行了!
  

           

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow
这里写图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值