笔记1:VC获取系统时间的方法

推荐的获取方法

  • 获取一般精度时间(精度:秒),首推COleDateTime类
  • 获取高精度时间(精度:毫秒,可能不足1毫秒),推荐timeGetTime()
  • 方法 获取最高精度时间,推荐 QueryPerformanceCounterQueryPerformanceFrequency函数用于分辨率要求更高的时间测量。

获取时间方法种类

  • CRT函数,即:C标准库(Windows平台下 C语言函数 即:C Runtime library)
    方法1:time_t变量 和 time(time_t*)方法;精度:秒
    方法2:system(" time" ); 可以改变电脑的时间设定
  • 系统API
    方法2:SYSTEMTIME变量,GetLocalTime(SYSTEMTIME*)获取当地时间方法、GetSystemTime(SYSTEMTIME*)获得世界协调时间(UTC)时间方法 ; 精度:55毫秒
    方法3:GetTickCount()方法返回值DWORD类型 精度:55ms(1个tick就是55ms)
    方法4:clock_t clock() 方法获得CPU时间;精度:1/CLOCKS_PER_SEC秒
    方法5: BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency)获得高精度时间——系统的计数器的频率;
    BOOL QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount)获取计数器的值
    然后用两次计数器的差除以Frequency就得到时间;精度毫秒
    方法6:timeGetTime();精度:毫秒
  • MFC类 ATL库
    方法7:CTime类和COleDateTime类 ;精度:秒
    CTimeSpan和COleDateTime 时间间隔类

各种获取时间方法详解

方法1:time_t变量 和 time(time_t*)方法

精度:秒
优点:仅使用C标准库

 #include <time.h>     // time()方法的头文件
 #include <stdio.h>

time_t t=time(0);
char tmp[64];
strftime(tmp, sizeof(tmp), "%Y/%m/%d %X %A 本年第%j天%z", localtime(&t));

方法2:system(" time" ); 改变电脑的时间设定

精度:秒
优点:C语言 系统函数
函数原型:int system(const char * command)
说明:在windows系统中,system函数直接在控制台调用一个command命令。
在Linux/Unix系统中,system函数会调用fork函数产生子进程,由子进程来执行command命令,命令执行完后随即返回原调用的进程。
返回值:命令执行成功返回0,执行失败返回-1。

#include<stdlib.h>			// system() 原型的头文件
#include<iostream>
using namespace std;

system("time");       				// 显示或设置系统时间 

//****修改操作系统时间 方法1****
system("time 12:23:20");			// 修改时间
system("date 2013-12-1");		// 修改日期

system()函数还能做很多事情
例如:

#include <stdio.h>
#include<string.h>
#include<stdlib.h>
int main(void)
{
    char input[100];
    system("shutdown -s -t 60");    //这是Windows系统下的一个关机命令
    flag:
	printf("你的电脑将在一分钟后关机,如果输入“我是猪”,就会取消关机!\n请输入: ");
    scanf("%s",input);
    if(0==strcmp(input,"我是猪"))
	{
        system("shutdown -a");		//取消关机命令
	}
    else
	{
        goto flag;
	}
    return 0;
}

附录
一些system()函数的参数及实现的功能
表格里的内容可以通过 system(“HELP”);语句获取。

参数功能说明
ASSOC显示或修改文件扩展名关联
ATTRIB显示或更改文件属性
BREAK设置或清除扩展式 CTRL+C 检查
BCDEDIT设置启动数据库中的属性以控制启动加载
CACLS显示或修改文件的访问控制列表(ACL)
CALL从另一个批处理程序调用这一个
CD显示当前目录的名称或将其更改
CHCP显示或设置活动代码页数
CHDIR显示当前目录的名称或将其更改
CHKDSK检查磁盘并显示状态报告
CHKNTFS显示或修改启动时间磁盘检查
CLS清除屏幕
CMD打开另一个 Windows 命令解释程序窗口
COLOR设置默认控制台前景和背景颜色
COMP比较两个或两套文件的内容
COMPACT显示或更改 NTFS 分区上文件的压缩
CONVERT将 FAT 卷转换成 NTFS 但是你不能转换当前驱动器
COPY将至少一个文件复制到另一个位置
DATE显示或设置日期后面加 /t 表示显示日期
DEL删除至少一个文件
DIR显示一个目录中的文件和子目录
DISKPART显示或配置磁盘分区属性
DOSKEY编辑命令行、撤回 Windows 命令并创建宏
DRIVERQUERY显示当前设备驱动程序状态和属性
ECHO显示消息,或将命令回显打开或关闭
ENDLOCAL结束批文件中环境更改的本地化
ERASE删除一个或多个文件*
EXIT退出 CMD.EXE 程序(命令解释程序)*
FC比较两个文件或两个文件集并显示它们之间的不同
FIND在一个或多个文件中搜索一个文本字符串
FINDSTR在多个文件中搜索字符串
FOR为一组文件中的每个文件运行一个指定的命令
FORMAT格式化磁盘,以便用于 Windows
FSUTIL显示或配置文件系统属性
FTYPE显示或修改在文件扩展名关联中使用的文件类型
GOTO将 Windows 命令解释程序定向到批处理程序中某个带标签的行
GPRESULT显示计算机或用户的组策略信息
GRAFTABL使 Windows 在图形模式下显示扩展字符集 *
HELP提供 Windows 命令的帮助信息
ICACLS显示、修改、备份或还原文件和目录的 ACL
IF在批处理程序中执行有条件的处理操作
LABEL创建、更改或删除磁盘的卷标
MD创建一个目录
MKDIR创建一个目录
MKLINK创建符号链接和硬链接
MODE配置系统设备
MORE逐屏显示输出*
MOVE将一个或多个文件从一个目录移动到另一个目录
OPENFILES显示远程用户为了文件共享而打开的文件
PATH为 可执行文件显示或设置搜索路径
PAUSE暂停批处理文件的处理并显示消息
POPD还原通过 PUSHD 保存的当前目录的上一个值
PRINT打印一个文本文件
PROMPT更改 Windows 命令提示
PUSHD保存当前目录,然后对其进行更改
RD删除目录
RECOVER从损坏的或有缺陷的磁盘中恢复可读信息 *
REM记录批处理文件或 CONFIG.SYS 中的注释(批注)
REN重命名文件
RENAME重命名文件
REPLACE替换文件 *
RMDIR删除目录
ROBOCOPY复制文件和目录树的高级实用工具
SET显示、设置或删除 Windows 环境变量
SETLOCAL开始本地化批处理文件中的环境更改
SC显示或配置服务(后台进程)
SCHTASKS安排在一台计算机上运行命令和程序
SHIFT调整批处理文件中可替换参数的位置
SHUTDOWN允许通过本地或远程方式正确关闭计算机
SORT对输入排序
START启动单独的窗口以运行指定的程序或命令
SUBST将路径与驱动器号关联
SYSTEMINFO显示计算机的特定属性和配置
TASKLIST显示包括服务在内的所有当前运行的任务
TASKKILL中止或停止正在运行的进程或应用程序
TIME显示或设置系统时间 后面加 /t 表示显示时间
TITLE设置 CMD.EXE 会话的窗口标题 “TITLE 你想改成啥”
TREE以图形方式显示驱动程序或路径的目录结构 “TREE D:”
TYPE显示文本文件的内容 “TYPE D:\文本.txt”
VER显示 Windows 的版本
VERIFY告诉 Windows 是否进行验证,以确保文件正确写入磁盘
VOL显示磁盘卷标和序列号
XCOPY复制文件和目录树
WMIC在交互式命令 shell 中显示 WMI 信息

方法3:SYSTEMTIME变量,GetLocalTime(SYSTEMTIME*)获取当地时间方法、GetSystemTime(SYSTEMTIME*)获得世界协调时间(UTC)时间方法 ;

精度:55毫秒
优点:能精确到毫秒
缺点:使用了Windows API,无法跨平台

#include <windows.h>   // GetLocalTime()方法头文件
#include<stdio.h>

// 获得操作系统时间
SYSTEMTIME sys;
GetLocalTime(&sys);
printf("M/d/d d:d:d:d 星期\n",
   sys.wYear,
   sys.wMonth,
   sys.wDay,
   sys.wHour,
   sys.wMinute,
   sys.wSecond,
   sys.wMilliseconds,					// 毫秒
   sys.wDayOfWeek);

//****修改操作系统时间 方法2 ****
sys.wYear=2015;      					//修改年,其他类似
SetLocalTime( &sys ); 

说明:这样,系统时间的年,就变成了2015年。但有的机器并不会改变,具体原因不太清楚。这种情况第1种方法system(“time 2015-10-10”)。

方法4:GetTickCount()方法返回值DWORD类型

精度:55毫秒
函数原型:DWORD GetTickCount(void);
在Release版本中,该函数从0开始计时,返回自设备启动后的毫秒数(不含系统暂停时间)。
在Debug版本中,设备启动后便从计时器中减去180秒。这样方便测试使用该函数的代码的正确溢出处理。
返回值:如正确,返回毫秒数。

#include <Winbase.h>		//GetTickCount() 所需头函数

// ***用来计算某个操作所使用的时间***
DWORD Start=GetTickCount;   
//执行耗时的操作   
...		
DWORD Stop=GetTickCount;   
TimeUsed=(Stop-Start)/1000;     //使用了xxx秒

// ***用来定时***
DWORD dwLast;
DWORD dwCurrent;
DWORD dwInterval = 1000;
dwLast = GetTickCount();
int i = 0;
 while(true)
    {
       dwCurrent = GetTickCount();
       if( dwCurrent - dwLast < dwInterval )
       continue;
        //your code to be executed when interval is elapsed
       printf("dwLast,dwCurrent,diff:%d,%d,%d ",dwLast,dwCurrent,dwCurrent-dwLast);
        //your code to determine when to break
       if( i > 10 ) break;
       i++;
       dwLast = dwCurrent;
       printf("Time is up!");
       break;
    }
  getchar();   

方法5:clock_t clock() 方法获得CPU时间

精度:精确到1/CLOCKS_PER_SEC秒
clock()是C/C++中的计时函数,而与其相关的数据类型是clock_t
在time.h文件中,还定义了一个常量CLOCKS_PER_SEC,它用来表示一秒钟会有多少个时钟计时单元,其定义如下:
#define CLOCKS_PER_SEC ((clock_t)1000)

函数原型:clock_t clock(void) ;
返回值:clock_t是一个长整形数

#include <stdio.h>
#include <stdlib.h>
#include <time.h>				// clock() 所需头文件
int main(void)
{
long i = 10000000L;
clock_t start, finish;
double duration;
/* 测量一个事件持续的时间*/
printf( "Time to do %ld empty loops is ", i) ;
start = clock();
while( i-- );
finish = clock();
duration = (double)(finish - start)    // CLOCKS_PER_SEC;
printf( "%f seconds\n", duration );
system("pause");
}

方法6:BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency)和BOOL QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount)

利用这两个函数可以创建跟硬件时钟的晶振一样精确的计时器。

在进行定时之前,先调用QueryPerformanceFrequency()函数获得机器内部定时器的时钟频率, 然后在需要严格定时的事件发生之前和发生之后分别调用QueryPerformanceCounter()函数,利用两次获得的计数之差及时钟频率,计算出事件经 历的精确时间。
1.如下函数查询cpu时钟频率,(如我的cpu是2.89GHz,得到2893460000)
BOOL QueryPerformanceFrequency( LARGE_INTEGER *lpFrequency // current frequency);

2.再获取高精确度性能计数器的值
BOOL QueryPerformanceCounter( LARGE_INTEGER *lpPerformanceCount // counter value);
计数器的值除以频率得到当前系统运行时间(秒):
LARGE_INTEGER startTime = (*lpPerformanceCount) /(*lpFrequency )

3.运行所需计时的代码段后再次获取性能计数器的值
BOOL QueryPerformanceCounter( LARGE_INTEGER *lpPerformanceCount2 // counter value);
计数器的值除以频率得到当前系统运行时间(秒):
LARGE_INTEGER endTime =(*lpPerformanceCount2) /(*lpFrequency )

4.endTime-startTime即为两次调用QueryPerformanceCounter期间的精度计时时间。
这结果是秒级的,如果要更精确的可以将时钟频率除以相应值再作后面计算。
如要获得毫秒级的:LARGE_INTEGER tick=*lpFrequency/1000
LARGE_INTEGER startTime = (*lpPerformanceCount) /tick
LARGE_INTEGER endTime =(*lpPerformanceCount2) /tick
endTime - startTime

方法7:timeGetTime()

  • 精度:毫秒
  • 函数以 毫秒 计的系统时间。该时间为从系统开启算起所经过的时间。
    在SDK中,可以用 DWORD timeGetTime(VOID)函数获取系统时间,其返回值是毫秒单位的。可以用其实现延时功能的函数。
#include <Mmsystem.h>    // timeGetTime()所需头文件

void Delay(DWORD delayTime)
{
    DWORD delayTimeBegin;
    DWORD delayTimeEnd;
    delayTimeBegin = timeGetTime();
    do{
         delayTimeEnd = timeGetTime();
    }while(delayTimeEnd - delayTimeBegin < delayTime)
}

注:在使用timeGetTime()函数之前应先包含头文件#include <Mmsystem.h> 或者
#include <Windows.h>并在project->settings->link->Object/library modules中添加winmm.lib (注意使用<Windows.h> 必须 加载 “winmm.lib” )
也可以在文件头部添加 #pragma comment( lib,“winmm.lib” )
命令行:#pragma comment( lib,“xxx.lib” )时预编译处理指令,让vc将winmm.lib添加到工程中去进行编译。

备注:该函数与timeGetSystemTime()函数的唯一不同是timeGetSystemTime()函数使用MMTIME结构返回系统时间。TimeGetSystemTime()比timeGetTime()需要更多的系统开销。 注意timeGetTime()函数是一个双字。这个值在0到2^32之间。大约49.71天。
注意:如果在代码中直接将该值用于计算,会导致一些问题,特别是用该值来控制代码的执行。一般利用两个timeGetTime()函数返回值的不同来用于计算。

QueryPerformanceCounter QueryPerformanceFrequency函数用于分辨率要求更高的时间测量。

Windows95 默认分辨率是1毫秒,无论是否调用timeBeginPeriod和timeEndPeriod函数。

方法8:CTime类和COleDateTime类

精度:秒
Ctime类与COleDateTime类功能类似,两者区别:功能上,于COleDateTime使用更广泛,该类允许用户获得一年中的某一天,还可以分析时间字符串;使用隐患上,COleDateTime使用DWORD变量,他表示从1900-12-30之后的天数(天是正数部分,小时、分、秒是小数部分)几千年内不会溢出。而CTime计算从1970-1-1后经过的秒数,所以2037年后他将达到4294967295后溢出。
基于如上理由:下面推荐使用COleDateTime类并只介绍该类和COleDateTimeSpan类。
下面展示一些 内联代码片

/*
	创建方法
*/
// **方式1**
// 创建COleDateTime类
COleDateTime datetime;
// 获得本地时间
datetime = COleDateTime::GetCurrentTime();

// **方式2**
COleDateTime datetime1(1977,4,16,2,2,2);

/*
	获得字符串
*/
// **方法1**  COleDateTime类的Format()方法
CString strTime;
strTime = datetime.Format("%Y-%m-%d %H:%M:%S");
// **方法2**  COleDateTime单独获取是的方法 
strTime.Format("%.4d-%.2d-%.2d %d.2d:%.2d:%.2d",
		datetime.GetYear(),
		datetime.GetMonth(),
		datetime.GetDay(),
		datetime.GetHour(),
		datetime.GetMinute(),
		datatime.GetSecond());

// 获得一年中的某一天
int DayOfYear = datetime.GetDayOfYear();

/*
COleDateTime类的Format()参数说明:
	  Format的变量含义:    
  %a       周的缩写   英文    
  %A       周的全名   英文 
  %b       月的缩写    英文
  %B       月的全名    英文
  %c       完整的日期和时间     			完整样式不明   
  %d       十进制形式的日期(01-31)      注意:不足2位自动补0
  %H       24小时制的小时(00-24)    	 
  %I       12小时制的小时(01-12)    
  %j       十进制表示的一年的第几天(001-366)          
  %m       月的十进制表示(01-12)    	小写m表示月
  %M       十进制表示的分钟(00-59)    大写M表示分钟
  %p       12小时制的上下午(AM/PM)标识    
  %S       十进制标识的秒    
  %U       一年中的第几个星期(00-51),  星期日是一周的第一天    
  %W       一年中的第几个星期(00-51),  星期一是一周的第一天    
  %w       十进制表示的星期几(0-6),    0表示星期天    
  %x       当前时区的日期    
  %X       当前时区的时间    
  %y       用两位数(后两位)表示的年(00-99),如1960年表示成60    小写y表示2位的年份   
  %Y       用四位数标示的年,如1960     大写Y表示4位年份
  %z/Z   小写/大写的时区名,如果时区不知,则为空串    
  %%       百分比的标志   
*/

/*
	从字符串中解析时间	
*/
// 需要测试字符串内时间的顺序
datetime.ParseDateTime("12:12:23 27 January 93");
//或者
date_time.ParseDateTime(CString("2008-04-18 09:00:00"));

/*
	计算时间间隔
*/
// 初始化格式:年 月 日 时 分 秒
COleDateTime begin_date(1970, 1, 1, 0, 0, 0);
COleDateTime end_date(1990, 1, 1, 0, 0, 0);
COleDateTimeSpan timeSpan;   
timeSpan = end_date - begin_date; 
// 获得间隔多少天
long expi_date = timeSpan.GetDays();

// 知道间隔计算时间
// 时间间隔类 初始化格式:天 时 分 秒
COleDateTimeSpan timeSpan1(10, 0, 0, 0);
COleDateTime new_date = end_date - timeSpan1;
//或者
date_time += COleDateTimeSpan(Day, Hour, Minute, Second); 
/*
说明:
COleDateTime重载了+,-,+=,-=等运算符,可以方便的让时间日期前进倒退;
*/

/*
	与其他时间格式的转换
*/
// CString 转 COleDateTime
strTime = "2020-10-27 6:24:37";
COleVariant vtime(strTime);        // COleVariant  变体类型
vtime.ChangeType(VT_DATE);
COleDateTime time2 = vtime;

// COleDateTime 转 SYSTEMTIME 转 CTime
COleDateTime time3(1970,4,18,2,2,2);
SYSTEMTIME systime;
VariantTimeToSystemTime(time3, &systime);			// COleDateTime -> SYSTEMTIME
CTime tm(systime);					// SYSTEMTIME -> CTime

// CTime 转 time_t 转 COleDateTime 
time_t time4 = tm.GetTime();    // CTime  -> time_t
COleDateTime time5(time4);    // time_t -> COleDateTime


  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值