Zhi Wei 的个人博客
使用c++11 chrono库 输出时间 和 定时任务
使用c++11 chrono库 输出时间 和 定时任务

使用c++11 chrono库 输出时间 和 定时任务

在c++11以前都是直接使用标准c库ctime,c++11以后有了自己的时间头文件chrono。查看了微软的c++标准库参考后,我直接关闭了网页。基本参悟不了。看了几个文章以后,大概了解了一点,这个头文件基本用法。这边记录一下:

1.如何输出日期时间

常用输出时间日期和日期的方式是创建一个time_t的变量,使用time(0)函数赋值从1970年到现在一共经过了多少秒。是一个很长很长的数值,然后再通过ctime(),或者localtime()的方式格式化成人类能接受的时间比如:

	time_t now = time(0);
	tm ttm;
	localtime_s(&ttm,&now);
	tm* ltm = &ttm;
	cout << "年: " << 1900 + ltm->tm_year << endl;
	cout << "月: " << 1 + ltm->tm_mon << endl;
	cout << "日: " << ltm->tm_mday << endl;
	cout << "时间: " << ltm->tm_hour << ":";
	cout << ltm->tm_min << ":";
	cout << ltm->tm_sec << endl;
        char cstr[50] = { '\0' };
	time_t now = time(0);
	ctime_s(cstr, sizeof(cstr), &now);
	cout << cstr << endl;

2.使用chrono库定义now变量

        chrono::time_point<chrono::system_clock> tp(chrono::system_clock::now());
        now = chrono::system_clock::to_time_t(tp);  //将time_point转成time_t
	//.......

这里我们用chrono库的定义方法初始化now变量,然后将time_point类型的变量now转换成time_t类型赋值给now。其实还是一个很长很长的数值,time_point代表一个准确的时间节点,比如”1999年的1月23日23:32:11“,方法time_since_epoch()返回与时钟的纪元(或时钟开始测量时间的时间和日期)之间的时间量。可以打印”time_since_epoch().count();“观察数据。

通过time_point类型的变量,可以生成一个日期,比如:

	chrono::time_point<chrono::system_clock> tp;
	chrono::hours hh(72);
	tp += hh;
	char cstr[50] = { '\0' };
	time_t now = chrono::system_clock::to_time_t(tp);
	ctime_s(cstr, sizeof(cstr), &now);
	cout << cstr << endl;

输出的时间是1970年的1月4日8点,因为UTC时间+8是中国时区,如果我们不进行+=操作,那么时间就是1月1日8点,那么chrono::hours类型的变量又是什么呢?这个函数原型是duration<int, ratio<3600>> ,duration类型表示一个时间的长度,可以精确到微秒,表达方法需要使用ratio库进行定义,比如3.1415926秒,当般小程序当然用不着如此高精度的时间,常用已经定义好的还有:

名称说明
typedef duration<long long, nano> nanoseconds;刻度周期为十亿分之一 (1/1,000,000,000) 秒的 duration 类型的同义词。
typedef duration<long long, micro> microseconds;刻度周期为一百万分之一 (1/1,000,000) 秒的 duration 类型的同义词。
typedef duration<long long, milli> milliseconds;刻度周期为千分之一 (1/1,000) 秒的 duration 类型的同义词。
typedef duration<long long> seconds;时钟周期为 1 秒的 duration 类型的同义词。
typedef duration<int, ratio<60>> minutes;时钟周期为 1 分钟的 duration 类型的同义词。
typedef duration<int, ratio<3600>> hours;时钟周期为 1 小时的 duration 类型的同义词。
参考微软文档Typedef部分

除了chrono::system_clock这个时钟,chrono还给我们提供一个时钟叫做chrono::steady_clock,因为system_clock会受到系统设定的影响,比如NTP或者手动设置了时区,steady_clock则不会,他是当前这个节点开始只向前推进,steady_clock::now()的返回值不会小于设置的时间节点,所以可以用来计算时长。

steady_clock 是单调时钟,这意味着它报告的时间只向前移动。 对 now 的调用返回的值始终小于或等于对 now 的下一个调用返回的值

steady_clock 可确保刻度之间的时间是恒定的,因此比使用系统时钟更适合测量间隔。 系统时钟提供时钟时间。 使用时钟时间测量运行时间的问题在于,在测量时间间隔时可能会修改时钟时间。 它可以通过与网络上的另一个时钟同步、转换到夏令时等方式进行修改。 steady_clock 不受这些调整的约束,因此它成为跟踪运行时间的首选方法。

3.定时 和 检测运行时长

int main()
{
	//记录程序开始执行时间
	auto start_t = chrono::steady_clock::now();
	//休眠1234毫秒
	Sleep(1234);
	//设置一个时间长度
	chrono::seconds sec(5);
	//在sec设定的时间内打印*
	int i = 0;
	auto do_start_t = chrono::system_clock::now();     //这里也可以用steady_clock
	auto do_end_t = do_start_t + sec;
	do
	{
		cout << "*";
		i++;
	} while (chrono::system_clock::now() < do_end_t);//如果时间没有到就一直执行
	cout << "\ndo一共打印了" << i << "个*号\n";
	//记录程序结束执行时间
	auto end_t = chrono::steady_clock::now();
	cout << "main一共执行了" << chrono::duration_cast<chrono::milliseconds>(end_t - start_t).count() << "毫秒\n";
	return 0;
}

可以看到do循环的判断条件是时间,start_t和end_t标记了程序一共运行了多久,最后使用duration_cast将结果转换为毫秒进行输出。chrono库的使用非常灵活,duration和time_point也定义了很多重载运行,可以直接用这两个类型进行比较和运算,而且在最新的c++20中可以使用更多的函数和方法。由于我所需要的功能都已经能够实现,所以就不继续深入研究了。

以上就是chrono库简单的使用,欢迎您批评指正和留言交流。

参考链接:

https://learn.microsoft.com/zh-cn/cpp/standard-library/chrono?view=msvc-170

http://events.jianshu.io/p/170164adae0f

https://www.runoob.com/cplusplus/cpp-date-time.html

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注