utc时间 单位换算_UTC转换本地时间

//=====================================================================

//TITLE:

//    UTC转换本地时间

//AUTHOR:

//    norains

//DATE:

//    Friday 26- March-2010

//Environment:

//     WINDOWS XP

//     WINDOWS CE

//=====================================================================

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

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

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的声明:typedef struct _FILETIME {

DWORD dwLowDateTime;

DWORD dwHighDateTime;

} FILETIME;

问题就来了,FILETIME是一个结构体,包含了两个成员,我们无法直接进行算术运算!

别急,问题还不是很严重。仔细观察一下,FILETIME是由两个DWORD组成,每个DWORD是32bit,一共64bit。那么,我们直接用一个64bit的变量存储该数值,不就可以简单地进行运算了?

所以,我们WinCE下自力更生的SystemTimeToTzSpecificLocalTime函数出炉了: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(ddwLocalTime);

ftLocalTime.dwHighDateTime = static_cast(ddwLocalTime >> 32);

//将FILETIME数值转换为SYSTEMTIME格式并返回

return FileTimeToSystemTime(&ftLocalTime,lpLocalTime);

}

因为该函数的接口和WinXP的一模一样,所以文章开头的代码,我们可以不用做任何更改就能正确地在WinCE中运行了!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值