C语言时间函数的应用
C语言时间函数的应用 C语言程序,常涉及时间的获取和计算,例如获取当前时间,倒计时计算,时间差计算。 C/C++语言提供了一些库函数,可用于此目的。下面以VC++ 6.0 编译器为例,叙述C语言时间函数的应用,调用时间函数需头文件time.h。 (1)获取现在时间并打印 C语言提供函数 time(),可以获取现在时间。函数原型是 time_t time ( time_t *t); 你可以通过实参获取时间,也可以通过返回值获取时间。例如: time_t now; now = time(NULL); 或 time(&now); 得到的time_t型数值是从1970年1月1日起到现在的秒数。 用C语言提供的函数 ctime 转换成字符串形式,打印出年月日时分秒。 见下面程序里的 print_current_time() 子程序。 (2)获取现在时间并转换成整数年月日时分秒形式 C语言提供的函数localtime(), 可以把 time_t 数值转换成 tm 结构,tm结构里含年月日时分秒和是否是闰年等信息,结构里的年加1900是真实的年,结构里的月加1是真实的月。 见子程序 get_current_YMD(). (3)输入年月日计算这天是该年的第几天 当我们要绘制某年度的统计数据时,常以天做横座标按比例绘图,这时就需要把月日换算为天。 把日加上前几个月的天数就可得结果。只要注意该年是平年还是闰年,闰年的2月份多一天。闰年的判断是: if ((Y%4==0)&&(Y%100!=0)||(Y%400==0) {printf("闰年");} 见子程序 YMD_2_JD(); (4)输入年月日计算这天是星期几 公元计年从1年1diff函数月1日开始,这天是星期一。平年一年有365天,365除7取余数为1。也就是说平年的星期几等于上一年的星期几加1。闰年的星期几等于上一年的星期几加2。 所以,若知年份,就可以推算出这年元旦推移了多少天,变星期几,再调用YMD_2_JD(),算出某月某日推移了多少天,就算得这天是星期几。 见子程序 YMD_2_WeekDay()。 (5)输入整型值年月日时分秒转换为time_t 库函数 mktime,可以把 tm 结构 转换为 time_t。 我们可以用localtime把当前时间转为tm 结构,再修改里面的年月日时分秒,这样,tm 里的其它项,例如星期几,这天是该年的第几天等成员变量会自动改正,不须自己操心。然后调mktime,得到 time_t型时间值。 (6)暂停多少秒或多少毫秒的控制 暂停,可以用 Windows.h 里的 Sleep() 函数,也可以自己写。 Sleep(1000); 参数是1000毫秒,就是暂停 1 秒。一般人认为,Sleep函数,每秒可能有25毫秒误差。 自己写,可以利用 clock () 函数,clock () 函数送返从程序开始运行到调用时的时间间隔,单位是毫秒。暂停开始,用clock () 取开始时间,然后,只要用clock ()再取时间,判断是否到结束时间,没到则继续暂停。 见子程序 wait (int seconds) 和 wait_ms ( int ms )。 (7)倒计时 输入目标年月日时分秒,显示倒计时。 先把目标日期转换为time_t,然后取当前时间,用库函数 difftime()计算时间差单位秒,折算成倒计时时分秒。 见子程序 time_down() (8)时间差计算 获取时间差有多种方法。简单方法是用clock()函数。clock()函数返回当时时间读数,计时开始用clock()得到开始时间,计时结束,用clock()得到结束时间,两个数相减就是时间差,单位是毫秒。 见子程序example_dt_ms()。 另一种方法是用QueryPerformanceCounter()函数返回当时时钟读数,计时开始用它得到开始读数,计时结束用它得到结束读数,两个数相减是时间差读数。读数转换为时间,要用QueryPerformanceFrequency()函数获得时钟频率,读数除以时钟频率,得时间,单位是秒。乘1000得毫秒。据说,这种方法比较精确。 见子程序accurate_dt_ms()。 还有一种方法是用Pentium芯片汇编指令 0x0F 和 0x31,读取时钟计数图章,类似QueryPerformanceCounter()函数,计时开始和结束分别调用一次,得读数差,并扣除执行一次调用函数消耗的额外时间。读数差怎样转化成时间是个问题,如果知道CPU速度可以算得时间,如果知道时间,可以估算CPU速度。子程序 get_CPU_speed() 计算CPU的速度,单位 百万赫。 完整的C语言示范程序如下: #define NOMINMAX #include <windows.h> #include <stdio.h> #include <time.h> #include <math.h> char *WeekDayName[]={" ","Mon","Tue","Wen","Thu","Fri","Sat","Sun"}; void example_dt_ms(); void accurate_dt_ms(); void print_current_time(); void get_current_YMD(int *Y,int *M,int *D,int *hh,int *mm, int *ss); void get_current_tm(struct tm * timeinfo); int YMD_2_JD(int Y, int M, int D); int YMD_2_WeekDay(int Y, int M, int D); // 1,2,3,4,5,6,7 void wait ( int seconds ); void wait_ms ( int ms ); time_t YMD_hhmmss_2_s70(int Y, int M, int D, int hh, int mm, int ss); void check_mk(int Y, int M, int D, int hh, int mm, int ss); void time_down(int Y, int M, int D, int hh, int mm, int ss); __forceinline unsigned _int64 My_clock(void); unsigned _int64 Start(void); unsigned _int64 Stop(unsigned _int64 m_start, unsigned _int64 m_overhead); void get_CPU_speed(); void main(){ int y,m,d,hh,mm,ss,jd,wd; example_dt_ms(); accurate_dt_ms(); print_current_time(); get_current_YMD(&y,&m,&d,&hh,&mm,&ss); printf("It is %d-%02d-%02d %02d-%02d-%02d int values\n",y,m,d,hh,mm,ss); jd=YMD_2_JD(y,m,d); printf("JD is %d\n",jd); wd = YMD_2_WeekDay(y,m,d); printf("weekday %d -- %s\n",wd,WeekDayName[wd]); get_CPU_speed(); time_down(2011,10,1,0,0,0); exit(0); } void example_dt_ms() { clock_t tick1,tick2; int i,j,k; double dt; tick1=clock(); //ms //for (i=0;i<1000;i++) for (j=0;j<1000;j++) for (k=0;k<100;k++) {}; wait_ms(2000); tick2=clock(); dt = (double) (tick2 - tick1); printf("==============\nexample_dt_ms:\n"); printf("dt = %lf ms\n",dt); } void accurate_dt_ms() { LARGE_INTEGER nFreq; LARGE_INTEGER nBeginTime; LARGE_INTEGER nEndTime; int executionTime; double dt,d_freq,d_begin_t,d_end_t; // Start of time interval QueryPerformanceFrequency(&nFreq); d_freq = (double) nFreq.QuadPart; QueryPerformanceCounter(&nBeginTime); // Any code // ... wait_ms(2000); // End of time interval QueryPerformanceCounter(&nEndTime); // time interval in ms executionTime = (nEndTime.QuadPart - nBeginTime.QuadPart) * 1000 / nFreq.QuadPart; dt = (double) ((nEndTime.QuadPart - nBeginTime.QuadPart) * 1000) / d_freq; printf("==============\naccurate_dt_ms:\n"); printf("dt=%d in ms or dt=%lf ms\n", executionTime,dt); } void print_current_time() { time_t seconds; struct tm *t; char str[80]; seconds = time ( NULL); printf("==============\nprint_current_time:\n"); printf("%ld hours since January 1, 1970\n", seconds/3600); printf( "The current local date/time is: %s\n", ctime (&seconds) ); t = localtime(&seconds); printf("print in nicer format:\n"); strftime (str, 80, "Today is %A, %B %d.", t); printf("%s\n",str); strftime (str, 80, "The time is %I:%M %p.", t); printf("%s\n",str); } void get_current_YMD(int *Y,int *M,int *D,int *hh,int *mm, int *ss){ struct tm info,*t=&info; time_t rawtime; time ( &rawtime ); t = localtime(&rawtime); *Y = t->tm_year + 1900; *M = t->tm_mon + 1; *D = t->tm_mday; *hh = t->tm_hour; *mm = t->tm_min; *ss = t->tm_sec; } int YMD_2_JD(int Y, int M, int D){ const short MonthDay[]={0,31,28,31,30,31,30,31,31,30,31,30,31}; int JD,i; JD=D; for (i=1;i<M;i++) JD+=MonthDay[i]; if ((Y%4==0)&&(Y%100!=0)||(Y%400==0) && M>2) JD++; return JD; } int YMD_2_WeekDay(int Y, int M, int D){ int offset,jd,weekD; offset = ((Y-1)+(Y-1)/4-(Y-1)/100+(Y-1)/400) % 7 ; jd = YMD_2_JD(Y,M,D); weekD = (jd + offset) % 7; return weekD; } void wait ( int seconds ) { clock_t endwait; endwait = clock () + seconds * CLOCKS_PER_SEC ; while (clock() < endwait) {} } void wait_ms ( int ms ) { clock_t endwait; endwait = clock () + ms; while (clock() < endwait) {} } time_t YMD_hhmmss_2_s70(int Y, int M, int D, int hh, int mm, int ss){ struct tm *target_tm; time_t tt; time (&tt); target_tm=localtime(&tt); target_tm->tm_year = Y - 1900; target_tm->tm_mon= M - 1; target_tm->tm_mday = D; target_tm->tm_hour = hh; // hour target_tm->tm_min = mm; target_tm->tm_sec = ss; tt = mktime(target_tm); // from tm to time_t (s) return tt; } void time_down(int Y, int M, int D, int hh, int mm, int ss){ time_t target, now; long double dif,r; int d,h,m,s,k=0; target= YMD_hhmmss_2_s70(Y,M,D,hh,mm,ss); printf("time down to %d-%02d-%02d %02d-%02d-%02d\n",Y,M,D,hh,mm,ss); while (k < 5) { now = time(NULL); dif = difftime (target,now); d = (int) (dif / 86400.0); r = dif - d * 86400.0; h = (int) (r / 3600.0); r = r - h * 3600.0; m = (int) (r / 60.0); r = r - m * 60.0; s = (int) (r); printf("%d--days %d--hours %d--min %d--sec\n",d,h,m,s); (void) wait ( 2 ); // every 2 seconds print k = k + 1; } } // Pentium instruction "Read Time Stamp Counter". __forceinline unsigned _int64 My_clock(void) { _asm _emit 0x0F _asm _emit 0x31 } unsigned _int64 Start(void) { return My_clock();} unsigned _int64 Stop(unsigned _int64 m_start, unsigned _int64 m_overhead) {return My_clock()-m_start - m_overhead; } void get_CPU_speed() { unsigned _int64 m_start=0, m_overhead=0; unsigned int CPUSpeedMHz; m_start = My_clock(); m_overhead = My_clock() - m_start - m_overhead; printf("overhead for calling My_clock=%I64d\n", m_overhead); m_start = My_clock(); wait_ms(2000); CPUSpeedMHz=(unsigned int) ( (My_clock()- m_start - m_overhead) / 2000000); printf("CPU_Speed_MHz: %u\n",CPUSpeedMHz); |
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论