计时函数(一)

计时函数(一)

欢迎讨论http://www.cnblogs.com/jerry19880126/

所谓“时”,可以分成时间点和时间段两大类,时间点的概念就好比知道现在是几时几分,而时间段主要用于计量这段程序运行了多久,或者用于定时触发中断。C/C++中有多种方法可以实现计时。

1. 用time()得到时间点

需要包含头文件<time.h>或者是<ctime>,time()的函数原型为:

time_t time ( time_t * timer );

其中time_t是64位的整型,用于计算自1970年1月1日以来逝去的秒数,既可以通过返回值来得到秒数,也可以通过传入参数来获得秒数,函数的使用方法如下:

1 int main()
2 {
3     const time_t t = time(NULL); // time_t t = 0; time(&t);也可以
4     cout << "自1970年以来,已经过去了 " << t << "" << endl;
5 }

运行结果如下:

可以通过两次时间点之差来获得时间段。由time()得到的仅仅是一个很大的秒数,怎样才能将之转换成我们日常生活中能用到的年、月、日、时、分和秒呢?

 

2. 用localtime()得到有意义的时间点

需要包含头文件<time.h>或者是<ctime>,localtime()的函数原型如下:

struct tm * localtime ( const time_t * timer );

返回的是名为tm的结构体,而tm结构体中则存储了诸如年、月、日之类的有意义的时间点,函数的用法如下:

 1 int main()
 2 {
 3 const time_t t = time(NULL);
 4     tm* currentTime = localtime(&t);
 5     cout << "当前年:" << 1900 + currentTime->tm_year << endl
 6         << "当前月:" << currentTime->tm_mon + 1 << endl
 7         << "当前日:" << currentTime->tm_mday << endl
 8         << "当前时:" << currentTime->tm_hour  << endl
 9         << "当前分:" << currentTime->tm_min << endl
10         << "当前秒:" << currentTime->tm_sec << endl;
11     cout << "今天是星期 " << currentTime->tm_wday << endl
12         << "今天是年中的第 " << currentTime->tm_yday + 1 << "" << endl;
13 }

首先用time函数得到自元年以来逝去的秒数,接着由localtime(秒数)即可得到存储有意义时间点的结构体,tm结构体中的tm_year表示自1900年以来逝去的年,所以要输出现在是多少年,要记得加上1900;tm_mon表示当前月,注意这里的取值范围是[0, 11],所以对之+1则得到生活意义上的月;表示当前天的情况稍稍复杂一些,比如今年是2013年1月5日,常用的天是5,即今天是本月的第5天,用tm_mday表示,mday表示month day;也可以说今天是周六,即今天是本周的第6天,用tm_wday表示,wday表示week day;同样也可以说今天是整个一年中的第5天,即今天是本年的第5天,用tm_yday表示,yday表示year day,注意1月1号的tm_yday是0,所以对之+1以更符合生活上的概念。下面的时、分、秒的概念也就相对容易了,用tm_hour表示时,tm_min表示分,tm_sec表示秒。

上面程序的运行结果如下:

下面我们列个表总结一下:

tm_year            当前年(自1900年以来逝去的年数,一般对之+1900)

tm_mon            当前月(注意起始是0,所以一般对之+1)

tm_mday          当前日

tm_wday          星期几

tm_yday           年中的第几天(注意起始是0,所以一般对之+1)

tm_hour           当前时

tm_min             当前分

tm_sec             当前秒

如果你用的是Visual Studio的编译器,那么直接使用localtime()函数,编译器会给出warning,说这个函数不安全,并推荐使用localtime_s()。localtime_s()的函数接口如下:

errno_t localtime_s(

   struct tm* _tm,

   const time_t *time

);

我看了一下微软的文档,貌似这个函数对原来函数的“安全”改进就在于用返回值判断函数运行是否成功。所以很简单地,我们只要把上述程序传入的参数形式修改一下:

 1 int main()
 2 {
 3 const time_t t = time(NULL);
 4     tm currentTime = {0};
 5     int err = localtime_s(&currentTime, &t);
 6     if(err)
 7     {
 8         cout << "函数运行不成功!" << endl;
 9         exit(1);
10     }
11     cout << "当前年:" << 1900 + currentTime.tm_year << endl
12         << "当前月:" << currentTime.tm_mon + 1 << endl
13         << "当前日:" << currentTime.tm_mday << endl
14         << "当前时:" << currentTime.tm_hour  << endl
15         << "当前分:" << currentTime.tm_min << endl
16         << "当前秒:" << currentTime.tm_sec << endl;
17     cout << "今天是星期 " << currentTime.tm_wday << endl
18         << "今天是年中的第 " << currentTime.tm_yday + 1 << "" << endl;
19 }

tm结构体中能表示的最小单位是“秒”,在有些实时应用时,可能需要更精确的度量,该怎么办呢?

 

3. 用<windows.h>中的GetLocalTime()函数得到有意义的时间点

windows.h头文件中的GetLocalTime()函数可以精确到毫秒,函数接口如下:

void GetLocalTime(SYSTEMTIME* systemTime);

SYSTEMTIME是类似于tm的结构体,使用方法很简单,如下面的程序所示,

 1 int main()
 2 {
 3     SYSTEMTIME systemTime;
 4     GetLocalTime(&systemTime);
 5     cout << "当前年:" << systemTime.wYear << endl
 6         << "当前月:" << systemTime.wMonth << endl
 7         << "当前日:" << systemTime.wDay << endl
 8         << "当前时:" << systemTime.wHour << endl
 9         << "当前分:" << systemTime.wMinute << endl
10         << "当前秒:" << systemTime.wSecond << endl
11         << "当前毫秒:" << systemTime.wMilliseconds << endl;
12     cout << "当前是星期 " << systemTime.wDayOfWeek << endl;
13     return 0;
14 }

运行结果如下:

可以看到,SYSTEMTIME结构体中的成员都是生活意义上的,不用+1或者+1900来修正,其实看变量名也已经知道它的含义了,但在这里还是不妨做个表:

wYear                  当前年

wMonth               当前月

wDay                   当前日

wHour                 当前时

wMinute               当前分

wSecond              当前秒

wMilliseconds     当前毫秒

wDayOfWeek      当前是星期几

 

time(),localtime()以及GetLocalTime()都只需要系统自带的头文件即可,boost库中亦提供了很方便的计时函数,还提供了显示进度的功能,有的函数可以精确到微秒,我将在下一篇博文中进行介绍。

 

posted @ 2013-01-05 16:48  Jerry19880126  阅读(5952)  评论(2编辑  收藏  举报