C语言获取当前系统时间的几种方式

上传人:hs****ma 文档编号:567950533 上传时间:2024-07-22 格式:PDF 页数:25 大小:1.07MB
返回 下载 相关 举报
C语言获取当前系统时间的几种方式_第1页
第1页 / 共25页
C语言获取当前系统时间的几种方式_第2页
第2页 / 共25页
C语言获取当前系统时间的几种方式_第3页
第3页 / 共25页
C语言获取当前系统时间的几种方式_第4页
第4页 / 共25页
C语言获取当前系统时间的几种方式_第5页
第5页 / 共25页
点击查看更多>>
资源描述

《C语言获取当前系统时间的几种方式》由会员分享,可在线阅读,更多相关《C语言获取当前系统时间的几种方式(25页珍藏版)》请在金锄头文库上搜索。

1、.C 语言中如何获取时间?精度如何?1 使用 time_t time 精确到秒2 使用 clock_t clock 得到的是 CPU 时间精确到1/CLOCKS_PER_SEC 秒3 计算时间差使用 double difftime4 使用 DWORD GetTickCount 精确到毫秒5 如果使用 MFC 的 CTime 类,可以用 CTime:GetCurrentTime 精确到秒6 要获取高精度时间,可以使用BOOL QueryPerformanceFrequency获取系统的计数器的频率BOOL QueryPerformanceCounter获取计数器的值然后用两次计数器的差除以 Fr

2、equency 就得到时间。7 Multimedia Timer FunctionsThe following functions are used with multimedia timers.timeBeginPeriod/timeEndPeriod/timeGetDevCaps/timeGetSystemTime/*/用标准 C 实现获取当前系统时间的函数1 / 25.一.time函数time函数获取当前时间距1970年1月1日的秒数,以秒计数单位,存于 rawtime 中。#include time.hvoid main time_t rawtime;struct tm * timei

3、nfo;time ;timeinfo = localtime ;printf 007The current date/time is: %s, asctime ;exit;=#include - 必须的时间函数头文件time_t - 时间类型time.h 定义是 typedef long time_t; 追根溯源,time_t 是 longstruct tm - 时间结构,time.h 定义如下:int tm_sec;2 / 25.int tm_min;int tm_hour;int tm_mday;int tm_mon;int tm_year;int tm_wday;int tm_yday;

4、int tm_isdst;time ; - 获取时间,以秒计,从1970年1月一日起算,存于 rawtimelocaltime ; - 转为当地时间,tm 时间结构asctime - 转为标准 ASCII 时间格式:星期 月 日 时:分:秒 年-二.clock函数,用 clock函数,得到系统启动以后的毫秒级时间,然后除以 CLOCKS_PER_SEC,就可以换成秒,标准 c 函数。clock_t clock ;#include3 / 25.clock_t t = clock;long sec = t / CLOCKS_PER_SEC;他是记录时钟周期的,实现看来不会很精确,需要试验验证;-三

5、.gettime; 据说 tc2.0的 time 结构含有毫秒信息#include#includeint mainstruct time t;gettime;printf;return 0;time 是一个结构体, 其中成员函数 ti_hund 是毫秒。-4 / 25.四.GetTickCount,这个是 windows 里面常用来计算程序运行时间的函数;DWORD dwStart = GetTickCount;/这里运行你的程序代码DWORD dwEnd = GetTickCount;则就是你的程序运行时间, 以毫秒为单位这个函数只精确到55ms,1个 tick 就是55ms。-五.time

6、GetTimet,imeGetTime基本等于 GetTickCount,但是精度更高DWORD dwStart = timeGetTime;/这里运行你的程序代码DWORD dwEnd = timeGetTime;则就是你的程序运行时间, 以毫秒为单位虽然返回的值单位应该是 ms,但传说精度只有10ms。=/*Unix#unix 时间相关,也是标准库的/*5 / 25.1.timegm 函数只是将 struct tm 结构转成 time_t 结构,不使用时区信息;time_t timegm;2.mktime 使用时区信息time_t mktime;timelocal 函数是 GNU 扩展的与

7、 posix 函数 mktime 相当time_t timelocal ;3.gmtime 函数只是将 time_t 结构转成 struct tm 结构,不使用时区信息;struct tm * gmtime;4.localtime 使用时区信息struct tm * localtime;1.time 获取时间,stime 设置时间time_t t;t = time;2.stime 其参数应该是 GMT 时间,根据本地时区设置为本地时间;int stime3.UTC=true 表示采用夏时制;4.文件的修改时间等信息全部采用 GMT 时间存放,不同的系统在得到修改时间后通过 localtime6

8、 / 25.转换成本地时间;5.设置时区推荐使用 setup 来设置;6.设置时区也可以先更变/etc/sysconfig/clock 中的设置再将ln -fs /usr/share/zoneinfo/xxxx/xxx/etc/localtime 才能重效time_t 只能表示68年的范围,即 mktime 只能返回1970-2038这一段范围的 time_t看看你的系统是否有 time_t64,它能表示更大的时间范围/*windows#Window 里面的一些不一样的/*一.CTime 类VC 编程一般使用 CTime 类 获得当前日期和时间CTime t = GetCurrentTime;

9、SYSTEMTIME 结构包含毫秒信息typedef struct _SYSTEMTIME WORD wYear;WORD wMonth;WORD wDayOfWeek;7 / 25.WORD wDay;WORD wHour;WORD wMinute;WORD wSecond;WORD wMilliseconds; SYSTEMTIME, *PSYSTEMTIME;SYSTEMTIME t1;GetSystemTimeCTime curTime;WORD ms = t1.wMilliseconds;SYSTEMTIME sysTm;:GetLocalTime;在 time.h 中的_strti

10、me /只能在 windows 中用char t11;_strtime;puts;/*8 / 25.获得当前日期和时间CTime tm=CTime:GetCurrentTime;CString str=tm.Format;在 VC 中,我们可以借助 CTime 时间类,获取系统当前日期,具体使用方法如下:CTime t = CTime:GetCurrentTime; /获取系统日期,存储在 t 里面int d=t.GetDay; /获得当前日期int y=t.GetYear; /获取当前年份int m=t.GetMonth; /获取当前月份int h=t.GetHour; /获取当前为几时in

11、t mm=t.GetMinute; /获取当前分钟int s=t.GetSecond; /获取当前秒int w=t.GetDayOfWeek; /获取星期几,注意1为星期天,7为星期六二.CTimeSpan 类如果想计算两段时间的差值,可以使用 CTimeSpan 类,具体使用方法如下:CTime t1;CTime t = CTime:GetCurrentTime;CTimeSpan span=t-t1; /计算当前系统时间与时间 t1的间隔9 / 25.int iDay=span.GetDays; /获取这段时间间隔共有多少天int iHour=span.GetTotalHours; /获取

12、总共有多少小时int iMin=span.GetTotalMinutes;/获取总共有多少分钟int iSec=span.GetTotalSeconds;/获取总共有多少秒-三._timeb函数_timeb 定义在 SYSTIMEB.H,有四个 fieldsdstflagmillitmtimetimezonevoid _ftime;struct _timeb timebuffer;_ftime;取当前时间:文档讲可以到 ms,有人测试,好象只能到16ms!四.设置计时器定义 TIMER ID10 / 25.#define TIMERID_JISUANFANGSHI 2在适当的地方设置时钟,需要

13、开始其作用的地方;SetTimer;在不需要定时器的时候的时候销毁掉时钟KillTimer;对应 VC 程序的消息映射void CJisuan:OnTimerswitch-#如何设定当前系统时间-windowsSYSTEMTIME m_myLocalTime,*lpSystemTime;m_myLocalTime.wYear=2003;m_myLocalTime.wM;m_myLocalTime.wDay=1;m_myLocalTime.wHour=0;m_myLocalTime.wMinute=0;m_myLocalTime.wSec;11 / 25.m_myLocalTime.wMilli

14、sec;lpSystemTime=&m_myLocalTime;if SetLocalTime /此处换成 SetSystemTime也不行MessageBox;elseMessageBox;SYSTEMTIME m_myLocalTime,*lpSystemTime;m_myLocalTime.wYear=2003;m_myLocalTime.wM;m_myLocalTime.wDay=1;lpSystemTime=&m_myLocalTime;if SetDate /此处换成 SetSystemTime也不行MessageBox;elseMessageBox;本文来自 CSDN 博客,转载

15、请标明出处:一种制作微秒级精度定时器的方法12 / 25.当使用定时器时,在很多情况下只用到毫秒级的时间间隔,所以只需用到下面的两种常用方式就满足要求了。一是用SetTimer函数建立一个定时器后,在程序中通过处理由定时器发送到线程消息队列中的 WM_TIMER 消息,而得到定时的效果退出程序时别忘了调用和 SetTimer 配对使用的KillTimer 函数。二是利用 GetTickCount 函数可以返回自计算机启动后的时间 ,通过两次调用GetTickCount 函数,然后控制它们的差值来取得定时效果 ,此方式跟第一种方式一样,精度也是毫秒级的。用这两种方式取得的定时效果虽然在许多场合已

16、经满足实际的要求 ,但由于它们的精度只有毫秒级的,而且在要求定时时间间隔小时,实际定时误差大。下面介绍一种能取得高精度定时的方法。在一些计算机硬件系统中,包含有高精度运行计数器high-resolution performance counter,利用它可以获得高精度定时间隔,其精度与 CPU 的时钟频率有关。采用这种方法的步骤如下:1、首先调用 QueryPerformanceFrequency 函数取得高精度运行计数器的频率 f。单位是每秒多少次n/s,此数一般很大。2、在需要定时的代码的两端分别调用 QueryPerformanceCounter 以取得高精度运行计数器的数值 n1,n2

17、。两次数值的差值通过 f 换算成时间间隔,t=/f。下面举一个例子来演示这种方法的使用及它的精确度。在 VC 6.0 下用 MFC 建立一个对话框工程,取名为 HightTimer.在对话框面板中控件的布局如下图:其中包含两个静态文本框 ,两个编辑框和两个按纽 。上面和下面位置的编辑框的ID 分别为IDC_E_TEST 和 IDC_E_ACTUAL,通过 MFC ClassWizard 添加的成员变量也分别对应为 DWORDm_dwTest 和 DWORD m_dwAct. 退出按纽的 ID 为 IDOK,开始测试按纽 ID 为 IDC_B_TEST,13 / 25.用 MFC ClassWi

18、zard 添加此按纽的单击消息处理函数如下:void CHightTimerDlg:OnBTest/ TODO: Add your control notification handler code hereUpdateData; /取输入的测试时间值到与编辑框相关联的成员变量 m_dwTest中LARGE_INTEGER frequence;if!QueryPerformanceFrequency /取高精度运行计数器的频率 ,若硬件不支持则返回 FALSEMessageBox;LARGE_INTEGER test, ret;test.QuadPart = frequence.QuadPar

19、t * m_dwTest / 1000000; / 通过频率换算微秒数到对应的数量与 CPU 时钟有关,1秒=1000000微秒ret = MySleep; /调用此函数开始延时,返回实际花销的数量m_dwAct = ; /换算到微秒数UpdateData; /显示到对话框面板14 / 25.其中上面调用的 MySleep 函数如下:LARGE_INTEGER CHightTimerDlg:MySleep/ 功能:执行实际的延时功能/ 参数:Interval 参数为需要执行的延时与时间有关的数量/ 返回值:返回此函数执行后实际所用的时间有关的数量/LARGE_INTEGER privious,

20、 current, Elapse;QueryPerformanceCounter;current = privious;while current.QuadPart - privious.QuadPart QueryPerformanceCounter;Elapse.QuadPart = current.QuadPart - privious.QuadPart;return Elapse;15 / 25.注:别忘了在头文件中为此函数添加函数声明。至此,可以编译和执行此工程了,结果如上图所示。在本人所用的机上测试,当测试时间超过3微秒时,准确度已经非常高了,此时机器执行本身延时函数代码的时间对需

21、要延时的时间影响很小了。上面的函数由于演示测试的需要,没有在函数级封装,下面给出的函数基本上可以以全局函数的形式照搬到别的程序中。BOOL MySleep/ 功能:执行微秒级的延时功能/ 参数:Interval 参数为需要的延时数单位:微秒/ 返回值:若计算机硬件不支持此功能,返回 FALSE,若函数执行成功,返回 TRUE/BOOL bNormal = TRUE;LARGE_INTEGER frequence, privious, current, interval;if!QueryPerformanceFrequency16 / 25.:MessageBox; /或其它的提示信息retur

22、n FALSE;interval.QuadPart = frequence.QuadPart * dwInterval / 1000000;bNormal = bNormal & QueryPerformanceCounter;current = privious;while current.QuadPart - privious.QuadPart bNormal = bNormal & QueryPerformanceCounter;return bNormal;需要指出的是,由于在此函数中的代码很多 ,机器在执行这些代码所花费的时间也很长 ,所以在需要 几 个 微 秒 的 延 时 时 ,

23、会 影 响 精 度 。 实 际 上 , 读 者 在 熟 悉 这 种 方 法 后 , 只 要 使 用QueryPerformanceFrequency 和 QueryPerformanceCounter 这两个函数就能按实际需要写出自己的延时代码了。使用 CPU 时间戳进行高精度计时17 / 25.对关注性能的程序开发人员而言,一个好的计时部件既是益友,也是良师。计时器既可以作为程序组件帮助程序员精确的控制程序进程,又是一件有力的调试武器,在有经验的程序员手里可以尽快的确定程序的性能瓶颈,或者对不同的算法作出有说服力的性能比较。在 Windows 平台下,常用的计时器有两种,一种是 timeGe

24、tTime 多媒体计时器,它可以提供毫秒级的计时。但这个精度对很多应用场合而言还是太粗糙了。另一种是QueryPerformanceCount 计数器,随系统的不同可以提供微秒级的计数。对于实时图形处理、多媒体数据流处理、或者实时系统构造的程序员 ,善用 QueryPerformanceCount/QueryPerformanceFrequency 是一项基本功。本文要介绍的,是另一种直接利用 Pentium CPU内部时间戳进行计时的高精度计时手段。以下讨论主要得益于Windows 图形编程一书,第15页17页,有兴趣的读者可以直接参考该书。关于RDTSC 指令的详细讨论,可以参考 Inte

25、l 产品手册。本文仅仅作抛砖之用。在 Intel Pentium 以上级别的 CPU 中,有一个称为时间戳Time Stamp的部件,它以64位无符号整型数的格式,记录了自 CPU 上电以来所经过的时钟周期数。由于目前的 CPU 主频都非常高,因此这个部件可以达到纳秒级的计时精度。这个精确性是上述两种方法所无法比拟的。在 Pentium 以上的 CPU 中,提供了一条机器指令 RDTSCRead Time Stamp Counter来读取这个时间戳的数字,并将其保存在EDX:EAX寄存器对中。由于EDX:EAX寄存器对恰好是Win32平台下C+语言保存函数返回值的寄存器,所以我们可以把这条指令

26、看成是一个普通的函数调用 。像这样:inline unsigned _int64 GetCycleCount18 / 25._asm RDTSC但是不行,因为RDTSC不被C+的内嵌汇编器直接支持,所以我们要用_emit伪指令直接嵌入该指令的机器码形式0X0F、0X31,如下:inline unsigned _int64 GetCycleCount_asm _emit 0x0F_asm _emit 0x31以后在需要计数器的场合,可以像使用普通的 Win32 API 一样,调用两次 GetCycleCount 函数,比较两个返回值的差,像这样:unsigned long t;t = GetCy

27、cleCount;/Do Something time-intensive .t -= GetCycleCount;Windows 图形编程第15页编写了一个类,把这个计数器封装起来。有兴趣的读者可以去参考那个类的代码。作者为了更精确的定时,做了一点小小的改进,把执行 RDTSC 指令的时间,通过连续两次调用 GetCycleCount 函数计算出来并保存了起来,以后每次计时结束后,都从实际得到19 / 25.的计数中减掉这一小段时间,以得到更准确的计时数字。但我个人觉得这一点点改进意义不大。在我的机器上实测,这条指令大概花掉了几十到100多个周期,在 Celeron 800MHz 的机器上,

28、这不过是十分之一微秒的时间。对大多数应用来说,这点时间完全可以忽略不计;而对那些确实要精确到纳秒数量级的应用来说,这个补偿也过于粗糙了。这个方法的优点是:1.高精度。可以直接达到纳秒级的计时精度在1GHz 的 CPU 上每个时钟周期就是一纳秒,这是其他计时方法所难以企及的。2.成本低 。timeGetTime 函数需要链接多媒体库winmm.lib,QueryPerformance* 函数根据MSDN 的说明,需要硬件的支持虽然我还没有见过不支持的机器和 KERNEL 库的支持,所以二者都只能在 Windows 平台下使用关于 DOS 平台下的高精度计时问题,可以参考图形程序开发人员指南,里面

29、有关于控制定时器8253的详细说明。但 RDTSC 指令是一条 CPU 指令,凡是 i386平台下 Pentium 以上的机器均支持,甚至没有平台的限制我相信 i386版本 UNIX 和 Linux 下这个方法同样适用,但没有条件试验,而且函数调用的开销是最小的。3.具有和 CPU 主频直接对应的速率关系。一个计数相当于1/秒,这样只要知道了 CPU 的主频 ,可以直接计算出时间 。这和 QueryPerformanceCount 不同,后者需要通过QueryPerformanceFrequency 获取当前计数器每秒的计数次数才能换算成时间。这个方法的缺点是:20 / 25.1.现有的 C/

30、C+编译器多数不直接支持使用 RDTSC 指令,需要用直接嵌入机器码的方式编程,比较麻烦。2.数据抖动比较厉害。其实对任何计量手段而言,精度和稳定性永远是一对矛盾 。如果用低精度的 timeGetTime 来计时,基本上每次计时的结果都是相同的;而 RDTSC 指令每次结果都不一样,经常有几百甚至上千的差距。这是这种方法高精度本身固有的矛盾。关于这个方法计时的最大长度,我们可以简单的用下列公式计算:自 CPU 上电以来的秒数 = RDTSC 读出的周期数 / CPU 主频速率Hz64位无符号整数所能表达的最大数字是 1.81019,在我的 Celeron 800上可以计时大约700年书中说可以

31、在200MHz的Pentium上计时117年,这个数字不知道是怎么得出来的,与我的计算有出入。无论如何,我们大可不必关心溢出的问题。下面是几个小例子,简要比较了三种计时方法的用法与精度/Timer1.cpp 使用了 RDTSC 指令的 Timer 类/KTimer 类的定义可以参见Windows 图形编程P15/编译行:CL Timer1.cpp /link USER32.lib#include 21 / 25.#include KTimer.hmainunsigned t;KTimer timer;timer.Start;Sleep;t = timer.Stop;printf;/Timer2

32、.cpp 使用了 timeGetTime 函数/需包含,但由于 Windows 头文件错综复杂的关系/简单包含比较偷懒:/编译行:CL timer2.cpp /link winmm.lib#include #include mainDWORD t1, t2;t1 = timeGetTime;22 / 25.Sleep;t2 = timeGetTime;printf;printf;printfLasting Time: %un,;/Timer3.cpp 使用了 QueryPerformanceCounter 函数/编译行:CL timer3.cpp /link KERNEl32.lib#incl

33、ude #include mainLARGE_INTEGER t1, t2, tc;QueryPerformanceFrequency;printf;QueryPerformanceCounter;Sleep;QueryPerformanceCounter;printf;printf;23 / 25.printfLasting Time: %un,;/以上三个示例程序都是测试1秒钟休眠所耗费的时间file:/测/试环境:Celeron 800MHz / 256M SDRAM/ Windows 2000 Professional SP2/ Microsoft Visual C+ 6.0 SP5/以下是 Timer1的运行结果,使用的是高精度的 RDTSC 指令Lasting Time: 804586872以下是 Timer2的运行结果,使用的是最粗糙的 timeGetTime APIBegin Time: 20254254End Time: 20255255Lasting Time: 1001以下是 Timer3的运行结果,使用的是 QueryPerformanceCount APIFrequency: 3579545Begin Time: 3804729124End Time: 380829883624 / 25.Lasting Time: 356971225 / 25

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 建筑/环境 > 施工组织

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号