之前浅学这块内容,C++11封装的如此冗长,于是“重学”加深影响,方便后续查阅
在std::chrono
命名空间下定义。
C语言虽然也有时间处理方法,但是精度只到秒。Linux 和 Windows 都有提供相应的方法精确到微秒,但是用法不同,显然不支持跨平台。chrono 库精度更高,同时支持跨平台 ,因此C++11之后使用chrono 库处理时间和日期是有必要的,至于到后面的C++版本是否会继续加强,那是以后的事情。
对于时间、日期的处理,它引入了三个基本概念:
时间(时钟):时间点的同上概念,包含时间点、时间间隔、日期
时间间隔(时间段):两个时间点的差值
时间点:比如 12:05:00 表示一个时间点,比如 2021-01-01 13:00:00 也表示一个时间点
时间段duration 1 2 3 4 5 template <class Rep , class Period = ratio<1 > >class duration; Rep: 表示时间的数量(例如,整数或浮点数) Period: 表示时间单位(例如,秒、毫秒、微秒等)
提供 count方法 获得计数值,还能进行运算符运算(加减乘除)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #include <iostream> #include <chrono> int main () { using namespace std::chrono; seconds five_seconds (5 ) ; seconds three_seconds (3 ) ; seconds total = five_seconds + three_seconds; seconds difference = five_seconds - three_seconds; seconds double_time = five_seconds * 2 ; seconds half_time = five_seconds / 2 ; std::cout << "Total time: " << total.count () << " seconds" << std::endl; std::cout << "Difference in time: " << difference.count () << " seconds" << std::endl; std::cout << "Double time: " << double_time.count () << " seconds" << std::endl; std::cout << "Half time: " << half_time.count () << " seconds" << std::endl; return 0 ; }
时间段可以应用于 wait_until 这种等到某个时间段的语句,下面介绍的时间点可以应用于 wait_for 这种等到某个时间点的语句
时间点time_point 用于表示时间点的类模板,和下面要介绍的clocks结合使用
创建对象不填写参数,代表构造一个以纪元为值的对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <iostream> #include <chrono> int main () { std::chrono::system_clock::time_point time_point1; time_t tt1 = std::chrono::system_clock::to_time_t (time_point1); std::cout<<ctime (&tt1); return 0 ; }
有两个成员方法:min和max代表time_point的最小值和最大值
测试最小值为空,最大值为Sat Apr 12 07:47:16 2262
前面介绍无参构造函数,还有两个构造函数没有介绍
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 explicit time_point (const duration& d) ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 time_point (const time_point& other) = default ;
系统时钟clocks (一)std::chrono::system_clock
now:可以用于获取当前时间
to_time_t:转换为 time_t
from_time_t:从time_t 转换
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <iostream> #include <chrono> int main () { std::chrono::system_clock::time_point curTime = std::chrono::system_clock::now (); time_t showTime = std::chrono::system_clock::to_time_t (curTime); std::cout<<"当前时间: " <<std::ctime (&showTime)<<std::endl; return 0 ; }
time_t 类型是C语言的时间类型,这就是实现C++和C语言时间类型的转换的
(二)std::chrono::steady_clock
不会被系统时间的调整所影响,且它的滴答频率是稳定的,适合用于测量时间间隔
只提供 now方法用于获取当前时间,测量时间间隔只需要调用两次now方法求差即可
(三)std::chrono::high_resolution_clock
提供了最高可能的时间分辨率。通常,它是 system_clock
或 steady_clock
的别名,但具体实现依赖于系统和标准库实现
同样只提供 now 方法用于获取当前时间
看来,测试时间间隔采用std::chrono::steady_clock(稳定,不受系统时间影响,因为原点是计算机启动的时刻),希望将时间转换为日历显示效果或者转换为C语言风格的时间类当采用std::chrono::system_clock(不稳定,如果被恶意修改系统时间,这里跟着受影响,通过 is_steady 判断是否稳定)
表示不同的时间单位 通过在构造函数中传递值,表示不同的时间类型,比方说你在 hours(1)代表一个小时,seconds(1)代表一秒
std::chrono::hours
:表示小时的持续时间
std::chrono::minutes
:表示分钟的持续时间
std::chrono::seconds
:表示秒的持续时间
std::chrono::milliseconds
:表示毫秒的持续时间
std::chrono::microseconds
:表示微秒的持续时间
std::chrono::nanoseconds
:表示纳秒的持续时间
转换为duration或time_point (一)duration_cast
用于将时间段从一种单位转换为另一种单位
1 2 template <class ToDuration , class Rep , class Period >constexpr ToDuration duration_cast (const duration<Rep, Period>& d) ;
把 秒 转换为 分钟,把 秒 转换为毫秒
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <iostream> #include <chrono> int main () { std::chrono::seconds sec (120 ) ; std::chrono::minutes min = std::chrono::duration_cast <std::chrono::minutes>(sec); std::cout << sec.count () << " seconds is " << min.count () << " minutes." << std::endl; std::chrono::milliseconds millisec = std::chrono::duration_cast <std::chrono::milliseconds>(sec); std::cout << sec.count () << " seconds is " << millisec.count () << " milliseconds." << std::endl; return 0 ; }
(二)time_point_cast
用于将时间点从一种单位转换为另一种单位
1 2 template <class ToDuration , class Clock , class Duration >constexpr time_point<Clock, ToDuration> time_point_cast (const time_point<Clock, Duration>& tp) ;
将当前时间点 转换为 毫秒精度,将当前时间点转换为秒精度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <iostream> #include <chrono> int main () { auto now = std::chrono::system_clock::now (); auto now_ms = std::chrono::time_point_cast <std::chrono::milliseconds>(now); auto epoch = now_ms.time_since_epoch (); auto value = std::chrono::duration_cast <std::chrono::milliseconds>(epoch); std::cout << "Current time in milliseconds since epoch: " << value.count () << "ms" << std::endl; auto now_sec = std::chrono::time_point_cast <std::chrono::seconds>(now); epoch = now_sec.time_since_epoch (); auto value_sec = std::chrono::duration_cast <std::chrono::seconds>(epoch); std::cout << "Current time in seconds since epoch: " << value_sec.count () << "s" << std::endl; return 0 ; }