使用chrono获取时间

使用chrono获取时间#

chrono自C++11以后加入了标准库,提供了精度和时间计算的接口。其中包含三种时钟system_clocksteady_clockhigh_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<>模板自定义一个精度,并且能够进行分数的计算,正如输出中显示的那样。

作者:cwtxx

出处:https://www.cnblogs.com/cwtxx/p/18718211

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   cwtxx  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示