您的位置:首页 > 其它

Windows中的时间(SYSTEMTIME和FILETIME)

2015-06-12 09:59 429 查看
原文地址:http://blog.csdn.net/bokee/article/details/5330791

上一篇中介绍了C运行库中的时间处理函数。这一篇介绍Windows SDk中提供的时间函数。两种时间系统之间没有本质区别(事实上CRT时间是用Windows时间实现的,当然这是说的VC实现),同样提供本地时间和UTC时间之间的转换。不过CRT中的tm时间在SDK中对应为系统时间(SYSTEMTIME),CRT中的time_t时间在SDK中对应的为文件时间(FILETIME),那个"特殊时刻"也变成1601年1月1日的子夜。

当然,首先要弄清楚FILETIME与SYSTEMTIME定义。

[cpp] view
plaincopy

typedef struct _FILETIME {

DWORD dwLowDateTime;

DWORD dwHighDateTime;

} FILETIME, *PFILETIME;

typedef struct _SYSTEMTIME {

WORD wYear;

WORD wMonth;

WORD wDayOfWeek;

WORD wDay;

WORD wHour;

WORD wMinute;

WORD wSecond;

WORD wMilliseconds;

} SYSTEMTIME, *PSYSTEMTIME;

比较一下,很明显,FILETIME与time_t类似,是64位整型,不过FILETIME是以100纳秒(ns)为单位。SYSTEMTIME与tm类似,不过多了一项wMilliseconds。可以看出,SDK时间比CRT的时间提供了更高的精度。同时SDK提供了更丰富的函数来处理时间。

[c-sharp] view
plaincopy

void GetSystemTime(

LPSYSTEMTIME lpSystemTime);

void GetLocalTime(

LPSYSTEMTIME lpSystemTime);

这两个函数获得SYSTEMTIME形式的当前时间,不过GetSystemTime函数获得当前的UTC时间,GetLocalTime获得当前的本地时间,可以想象,获得的两个时间存在着时差。类似于CRT中提供tm与time_t之间的转换,SDK也提供了两个函数来转换SYSTEMTIME时间与FILETIME时间。

[cpp] view
plaincopy

BOOL SystemTimeToFileTime(

const SYSTEMTIME* lpSystemTime,

LPFILETIME lpFileTime);

BOOL FileTimeToSystemTime(

const FILETIME* lpFileTime,

LPSYSTEMTIME lpSystemTime);

函数命名很self-explanatory,就不用多说了吧。

SDK还提供了两个很有趣的函数。

[cpp] view
plaincopy

BOOL LocalFileTimeToFileTime(

const FILETIME* lpLocalFileTime,

LPFILETIME lpFileTime);

BOOL FileTimeToLocalFileTime(

const FILETIME* lpFileTime,

LPFILETIME lpLocalFileTime);

LocalFileTimeToFileTime函数将本地的FILETIME时间转换为对应的UTC的FILETIME时间。我觉得,这个函数只是通过将本地时间减去与UTC时间的时间差来实现转换,比如在东八区的本地时间转换为对应的UTC时间,只需要将本地时间减去8*60*60*1000*1000*10(单位100ns)。类似,FileTimeToLocalFileTime函数是将UTC时间转换为本地时间,它只是将减去时间差换成加上时间差。

了解了这些功能,让我们用代码说话吧。

[cpp] view
plaincopy

#include <stdlib.h>

#include <stdio.h>

#include <time.h>

#include <windows.h>

int main()

{

SYSTEMTIME stLocal, stUTC, stUTC2;

FILETIME ftLocal, ftUTC, ft;

ULARGE_INTEGER uli;

GetLocalTime(&stLocal);

GetSystemTime(&stUTC);

printf("Local System Time(YYYY-MM-DD HH:MM:SS): %d-%d-%d %d:%d:%d/n", stLocal.wYear, stLocal.wMonth,

stLocal.wDay, stLocal.wHour, stLocal.wMinute, stLocal.wSecond);

printf("UTC System Time (YYYY-MM-DD HH:MM:SS): %d-%d-%d %d:%d:%d/n", stUTC.wYear, stUTC.wMonth,

stUTC.wDay, stUTC.wHour, stUTC.wMinute, stUTC.wSecond);

SystemTimeToFileTime(&stLocal, &ftLocal);

uli.LowPart = ftLocal.dwLowDateTime;

uli.HighPart = ftLocal.dwHighDateTime;

printf("Local File Time: %llu/n", uli.QuadPart);

LocalFileTimeToFileTime(&ftLocal, &ftUTC);

uli.LowPart = ftUTC.dwLowDateTime;

uli.HighPart = ftUTC.dwHighDateTime;

printf("UTC File Time: %llu/n", uli.QuadPart);

FileTimeToSystemTime(&ftUTC, &stUTC2);

printf("UTC System Time2 (YYYY-MM-DD HH:MM:SS): %d-%d-%d %d:%d:%d/n", stUTC2.wYear, stUTC2.wMonth,

stUTC2.wDay, stUTC2.wHour, stUTC2.wMinute, stUTC2.wSecond);

return EXIT_SUCCESS;

}

程序输出结果如下:



代码13行GetLocalTime函数获得当前的本地SYSTEMTIME时间,14行获得对应的UTC的SYSTEMTIME时间,如输出结果前两行所显示,两者相差8小时(凌晨还在写博客,表扬下自己。。。)。

20行SystemTimeToFileTime函数将本地SYSTEMTIME时间转换为方便计算的本地FILETIME形式时间,如输出结果第三行所显示。

25行LocalFileTimeToFileTime函数将本地FileTime时间转换为对应的UTC的FILETIME时间,如输出结果第四行所显示。就像前面介绍的,如果你将输出结果第三,四两行所显示的数字相减,并除以10*1000*1000*60*60,你将会得出8,你可以算下试试,记住FILETIME是以100纳秒为单位的。

最后30行FileTimeToSystemTime将FILETIME时间转换为SYSTEMTIME时间。可以看出输出结果中第五行与第二行相同,这是必须的,因为两者都是当前本地时间对应的UTC时间。

另一篇文章:http://blog.csdn.net/tracyzhongcf/article/details/3711684

typedef struct _FILETIME {

DWORD dwLowDateTime;

DWORD dwHighDateTime;

} FILETIME, *PFILETIME, *LPFILETIME;

typedef struct _SYSTEMTIME {

WORD wYear;

WORD wMonth;

WORD wDayOfWeek;

WORD wDay;

WORD wHour;

WORD wMinute;

WORD wSecond;

WORD wMilliseconds;

} SYSTEMTIME, *LPSYSTEMTIME;

FILETIME和SYSTEMTIME都只是记录时间的结构。

GetLocalTime能够得到本地电脑设置时区的时间,得到的类型是SYSTEMTIME的类型。

常用转换函数:

LONG WINAPI CompareFileTime(const FILETIME *lpft1, const FILETIME *lpft2);

BOOL WINAPI FileTimeToSystemTime(const FILETIME *lpft, LPSYSTEMTIME lpst);

BOOL WINAPI SystemTimeToFileTime(const SYSTEMTIME *lpst, LPFILETIME lpft);

BOOL WINAPI FileTimeToLocalFileTime(const FILETIME *lpft, LPFILETIME lpftLocal);

BOOL WINAPI LocalFileTimeToFileTime(const FILETIME *lpftLocal, LPFILETIME lpft);

那么,如果使用FILETIME来记录时间,需要加上n秒,如何进行累加计算呢?

#define PER_SECOND 1*10*1000*1000 //1秒

ULONGLONG ullSeconds = n* PER_SECOND;

FILETIME tTime;

ULARGE_INTEGER temp;

temp.QuadPart = ullSeconds;

tTime.dwHighDateTime = temp.HighPart;

tTime.dwLowDateTime = temp.LowPart;

依次类推,1小时就是36000000000;1天就是864000000000

说明:ULARGE_INTEGER 的结构定义如下

typedef union _ULARGE_INTEGER {

struct {

DWORD LowPart;

DWORD HighPart;

};

struct {

DWORD LowPart;

DWORD HighPart;

} u;

#endif //MIDL_PASS

ULONGLONG QuadPart;

} ULARGE_INTEGER;

typedef ULARGE_INTEGER *PULARGE_INTEGER;

可以看到,它是一个64位的联合体,它的空间大小就是64位,当使用QuadPart时等于是以64位的整体来使用的;

而若使用 LowPart和 HighPart时,等于是以高低32位来使用的。

因此,temp.QuadPart = ullSeconds;是给QuadPart赋值,实际上也就是给temp的内存空间赋值了,当然也可以通过LowPart和HighPart分别取出temp的低32位和高32位了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: