使用chrono获取时间
使用chrono获取时间#
chrono
自C++11以后加入了标准库,提供了精度和时间计算的接口。其中包含三种时钟system_clock
、steady_clock
和high_resolution_clock
,顾名思义,system_clock
是系统时钟,始终和系统的时间保持一致,因此在使用的过程中如果系统时间被修改了,那么使用了这个时钟的程序就会被影响。steady_clock
可以解决运行过程中系统时间被修改而被影响的问题,是一种稳定的单调时钟,所以更适合于度量时间间隔的场景。high_resolution_clock
定义上是一种高精度的时钟,其精度取决于系统环境可以达到的最小精度(不过我在windows平台上使用13.1版本的Mingw-w64测试了一下,cpu是13600kf,能显示的时间精度和系统时间是一样的,都是纳秒级别,也没体现出高精度的特点,可能是纳秒级精度已经比较高了的原因),使用到的场景似乎不多,前面两个已经够用了。
查看各个时钟的精度#
cout << "system_clock precision: ";
cout << chrono::system_clock::period::num << "/" << chrono::system_clock::period::den << endl;
cout << "steady_clock precision: ";
cout << chrono::steady_clock::period::num << "/" << chrono::steady_clock::period::den << endl;
cout << "chrono::high_resolution_clock precision: ";
cout << chrono::high_resolution_clock::period::num << "/" << chrono::high_resolution_clock::period::den << endl;
输出结果
system_clock precision: 1/1000000000
steady_clock precision: 1/1000000000
chrono::high_resolution_clock precision: 1/1000000000
公有静态成员函数 now#
三种时钟都有公有的静态成员函数now()
,返回当前的时间点,记录了从某一时刻到当前时间的时钟周期数。
chrono::time_point<chrono::steady_clock, chrono::nanoseconds> curTime = chrono::steady_clock::now();
cout << "time_since_epoch (steady_clock): \t\t" << curTime.time_since_epoch().count() << endl;
chrono::time_point high_curTime = chrono::high_resolution_clock::now();
cout << "time_since_epoch (high_resolution_clock): \t" << high_curTime.time_since_epoch().count() << endl;
chrono::time_point sys_curTime = chrono::system_clock::now();
cout << "time_since_epoch (system_clock): \t\t" << sys_curTime.time_since_epoch().count() << endl;
输出结果:
time_since_epoch (steady_clock): 117212202374400
time_since_epoch (high_resolution_clock): 1710767518931123200
time_since_epoch (system_clock): 1710767518931709300
系统时间返回的是世界协调时(Unix时间),从1970年1月1日00:00:00开始的时间,不计闰秒(从C++20起是规定,之前的标准没有明确指定,不过大多也是这么实现的)。高精度时钟也取了系统时间,不过这不是一定的,因为没有明确的标准指定高精度时钟必须这么做。而稳定时钟计算了从某刻开始到当前的时钟周期。
和C时间的转换#
系统时钟可以和C标准库中的时间结构进行转换,例如
time_t time_c = chrono::system_clock::to_time_t(sys_curTime);
cout << "system_clock::to_time_t: \t\t\t" << time_c << endl;
cout << "ctime: \t\t\t\t\t\t" << ctime(&time_c) << endl;
输出结果:
system_clock::to_time_t: 1710767518
ctime: Mon Mar 18 21:11:58 2024
顺便看一下C库中获取时间的结构
time_t now_c = time(NULL); // 返回从1900至今的秒数,入参不为NULL则也赋给time_t类型的入参
cout << "now: " << now_c << endl;
char *date = ctime(&now_c);
cout << "ctime(&now): " << date << endl; // 将时间戳转换成字符串
// 转换utc时间
tm *utcTime = gmtime(&now_c);
cout << "struct {\n" << " tm_year: " << utcTime->tm_year << " (since 1900)" << endl;
cout << " tm_month: " << utcTime->tm_mon << " (since 0)" << endl;
cout << " tm_yday: " << utcTime->tm_yday << endl;
cout << " tm_mday: " << utcTime->tm_mday << endl;
cout << " tm_wday: " << utcTime->tm_wday << endl;
cout << " tm_hour: " << utcTime->tm_hour << endl;
cout << " tm_minute: " << utcTime->tm_min << endl;
cout << " tm_second: " << utcTime->tm_sec << endl;
cout << "}tm;\n";
// 转成字符串输出
date = asctime(utcTime);
cout << date << endl;
输出:
now: 1710767518
ctime(&now): Mon Mar 18 21:11:58 2024
struct {
tm_year: 124 (since 1900)
tm_month: 2 (since 0)
tm_yday: 77
tm_mday: 18
tm_wday: 1
tm_hour: 13
tm_minute: 11
tm_second: 58
}tm;
Mon Mar 18 13:39:03 2024
需要引入ctime
库,使用time(NULL)
返还了从1900年至今的秒数,C中的时间结构精度只能到秒,所以需要更高精度的话,还是要去使用chrono
库。
不过ctime
库中的tm
结构可以表示年月日时分秒,倒是挺方便。
时间运算#
chrono::hours hour(1);
chrono::minutes minute(1);
auto diff = hour - minute; //得到的结果单位取小
cout << "1 hour - 1 minute = " << diff.count() << endl;
chrono::steady_clock::time_point steadyTimePoint;
cout << "curTimePoint - defaultTimePoint = " << chrono::duration_cast<chrono::nanoseconds>(curTime - steadyTimePoint).count() << endl; // 时间点和时间点相减得到时间段
// auto addTimePoint = curTime + steadyTimePoint; // 时间点之间不能相加
auto nextTimePoint = curTime + chrono::minutes{1}; // 时间点可以加时间段,得到下个时间点
cout << "当前时间点加一分钟: " << chrono::duration_cast<chrono::seconds>(nextTimePoint - steadyTimePoint).count() << endl;
// 时间段之间允许算数运算
chrono::minutes fourMinutes(4);
chrono::seconds twoSeconds(2);
cout << "4minutes + 2second = " << (fourMinutes + twoSeconds).count() << endl;
cout << "4minutes - 2second = " << (fourMinutes - twoSeconds).count() << endl;
// cout << "4minutes * 2second = " << (fourMinutes * twoSeconds).count() << endl; // 不允许时间相乘,没有意义
cout << "4minutes * 2 = " << (fourMinutes * 2).count() << endl;
cout << "4minutes / 2second = " << (fourMinutes / twoSeconds) << endl; // 时间段相除得到的是个值
chrono::seconds sevenSeconds(7);
cout << "4minutes % 7second = "s << (fourMinutes % sevenSeconds).count() << endl;
cout << "-----------------------------------------------------------------------------\n";
// 自定义时间段,第一个模板参数是数据类型,整数或者小数,第二个参数为比率
chrono::duration<int, ratio<1, 16>> sevenOfSixteen(7);
chrono::duration<int, ratio<1, 8>> OneOfEight(1);
cout << "7/16 - 3/8 = " << (sevenOfSixteen - OneOfEight).count() << endl; // 结果取小的单位 得到5个1/16
cout << "两个自定义的时间段不是倍数关系的情况下:" << endl;
chrono::duration<double, ratio<1, 11>> nineOfEleven(9.0);
chrono::duration<double, ratio<1, 7>> fiveOfSeven(5.0);
cout << "5.0/7 - 9.0/11 = " << (fiveOfSeven - nineOfEleven).count() << endl; // res = -8, 结果是取公倍数为分母的结果,也就是-8个1/77
输出结果:
1 hour - 1 minute = 59
curTimePoint - defaultTimePoint = 118836333058000
当前时间点加一分钟: 118896
4minutes + 2second = 242
4minutes - 2second = 238
4minutes * 2 = 8
4minutes / 2second = 120
4minutes % 7second = 2
-----------------------------------------------------------------------------
7/16 - 3/8 = 5
两个自定义的时间段不是倍数关系的情况下:
5.0/7 - 9.0/11 = -8
chrono
中时间的计算是通过ratio<>
来实现的,可以看到,1小时减去1分钟后,精度会取较小的单位,结果等于59。
chrono
内有时间点和时间段的概念,两个时间点相减可以得到两者相差的时间段,一个时间点可以加上一个时间段获取某个新的时间点,而两个时间点之间是不能相加的,这也符合日常生活中的印象。
我们还可以使用ratio<>
模板自定义一个精度,并且能够进行分数的计算,正如输出中显示的那样。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南