WINDOWS下的实现
这一篇介绍Windows SDk中提供的时间函数。两种时间系统之间没有本质区别(事实上CRT时间是用Windows时间实现的,当然这是说的VC实现),同样提供本地时间和UTC时间之间的转换。不过CRT中的tm时间在SDK中对应为系统时间(SYSTEMTIME),CRT中的time_t时间在SDK中对应的为文件时间(FILETIME),那个"特殊时刻"也变成1601年1月1日的子夜。
当然,首先要弄清楚FILETIME与SYSTEMTIME定义。
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提供了更丰富的函数来处理时间。
void GetSystemTime(LPSYSTEMTIME lpSystemTime);
voidGetLocalTime(LPSYSTEMTIME lpSystemTime);
这两个函数获得SYSTEMTIME形式的当前时间,不过GetSystemTime函数获得当前的UTC时间,GetLocalTime获得当前的本地时间,可以想象,获得的两个时间存在着时差。类似于CRT中提供tm与time_t之间的转换,SDK也提供了两个函数来转换SYSTEMTIME时间与FILETIME时间。
BOOL SystemTimeToFileTime(constSYSTEMTIME* lpSystemTime,LPFILETIME lpFileTime);
BOOL FileTimeToSystemTime(constFILETIME* lpFileTime,LPSYSTEMTIME lpSystemTime);
//函数命名很self-explanatory,就不用多说了吧。SDK还提供了两个很有趣的函数。
BOOL LocalFileTimeToFileTime(constFILETIME* lpLocalFileTime,LPFILETIME lpFileTime);
BOOL FileTimeToLocalFileTime(constFILETIME* lpFileTime,LPFILETIME lpLocalFileTime);
LocalFileTimeToFileTime函数将本地的FILETIME时间转换为对应的UTC的FILETIME时间。我觉得,这个函数只是通过将本地时间减去与UTC时间的时间差来实现转换,比如在东八区的本地时间转换为对应的UTC时间,只需要将本地时间减去8*60*60*1000*1000*10(单位100ns)。类似,FileTimeToLocalFileTime函数是将UTC时间转换为本地时间,它只是将减去时间差换成加上时间差。
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时间。
LINUX下的实现
int clock_gettime(clockid_t clk_id, struct timespect *tp);
clockid_t clk_id用于指定计时时钟的类型,对于我们Programmr以下三种比较常用:
CLOCK_REALTIME, a system-wide realtime clock.
CLOCK_PROCESS_CPUTIME_ID, high-resolution timer provided by the CPU for each process.
CLOCK_THREAD_CPUTIME_ID, high-resolution timer provided by the CPU for each of the threads.
struct timespect *tp用来存储当前的时间,其结构如下:
structtimespec {
time_t tv_sec; /* seconds */
longtv_nsec; /* nanoseconds */
};
下面是示例:
#include // for printf()
#include // for gettimeofday()
#include // for sleep()
usingnamespace std;
timespec diff(timespec start, timespec end);
int main()
{
timespec time1, time2;
inttemp;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
for(inti = 0; i < 242000000; i++)
temp += temp;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
cout <
return 0;
}
timespec diff(timespec start, timespec end)
{
timespec temp;
if((end.tv_nsec - start.tv_nsec) < 0)
{
temp.tv_sec = end.tv_sec - start.tv_sec - 1;
temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
}
else
{
temp.tv_sec = end.tv_sec - start.tv_sec;
temp.tv_nsec = end.tv_nsec - start.tv_nsec;
}
return temp;
}
在LINUX中可以使用函数gettimeofday()函数来得到时间。它的精度可以达到微妙
2.函数原型:
int gettimeofday(struct timeval*tv,struct timezone *tz )
3.说明:
gettimeofday()会把目前的时间用tv 结构体返回,当地时区的信息则放到tz所指的结构中
4.结构体:
1).
struct timeval{
long tv_sec;/*秒*/
long tv_usec;/*微妙*/
};
2).timezone 结构定义为:
struct timezone{
int tz_minuteswest;/*和greenwich 时间差了多少分钟*/
int tz_dsttime;/*type of DST correction*/
}
3).在gettimeofday()函数中tv或者tz都可以为空。如果为空则就不返回其对应的结构体。
4).函数执行成功后返回0,失败后返回-1,错误代码存于errno中。
#include // for printf()
#include // for gettimeofday()
#include // for sleep()
int delay(inttime)
{
inti, j;
for(i = 0; i < 5000; i++)
for(j = 0; j < 5000; j++)
;
}
int main()
{
structtimeval start;
structtimeval end;
unsignedlongdiff;
gettimeofday(&start, NULL);
delay(10);
gettimeofday(&end, NULL);
diff = 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec;
printf(“thedifference is % ld\n”, diff);
return 0;
}