chrono 标准库包含在头文件 中,使用时需要包含头文件,为了方便使用,可以导入命名空间
#include <chrono> using namespace std::chrono;
duration 关于时间的几个变量的定义 显示说明类型 using namespace std::chrono;using days = duration<int , std::ratio_multiply<std::ratio<24 >, hours::period>>;using weeks = duration<int , std::ratio_multiply<std::ratio<7 >, days::period>>;hours hour = 12 h; minutes minute = 30 min; seconds s = 10 s; milliseconds ms = 100 ms; microseconds us = 200u s; nanoseconds ns = 300 ns;
chrono 库中定义了 hours, minutes, seconds, milliseconds, microseconds, nanoseconds, 具体的定义如下:
using nano = ratio<1 , 1'000'000'000 >;using micro = ratio<1 , 1'000'000 >;using milli = ratio<1 , 1000 >;using nanoseconds = duration<int64_t , nano>;using microseconds = duration<int64_t , micro>;using milliseconds = duration<int64_t , milli>;using seconds = duration<int64_t >;using minutes = duration<int32_t , ratio<60 >>;using hours = duration<int32_t , ratio<3600 >>;
这里以秒为标准,其他的通过 duration 的第二个模板参数来建立和秒之间的关系,例如 1min = 60s
, 则第二个参数则为 ratio<60, 1>
。根据这个规则,可以定义其他的一些时间单位变量,例如:
using days = duration<int32_t , std::ratio_multiply<std::ratio<24 >, hours::period>>;using weeks = duration<int32_t , std::ratio_multiply<std::ratio<7 >, days::period>>;using frames = duration<int32_t , ratio<1 , 60 >>;
通过 auto 自动推断变量类型 auto hour = 12 h;auto minute = 30 min;auto s = 10 s;auto ms = 100 ms;auto us = 200u s;auto ns = 300 ns;
如何输出时间 chrono 库重新实现了 <<
操作符,因此可以直接使用该操作符对时间变量进行输出
std::cout << hour.count () << "h\n" ; std::cout << minute.count () << "min\n" ; std::cout << s.count () << "s\n" ; std::cout << ms.count () << "ms\n" ; std::cout << us.count () << "us\n" ; std::cout << ns.count () << "ns\n" ;
时间的计算和比较 各个时间变量是可以进行算术运算和比较运算的,支持的运算符包括 +
, -
, >
, >=
, <
, <=
, ==
, !=
seconds s1 = 10 s; seconds s2 = 200 s; seconds s3 = 200 s; std::cout << (s2 - s1).count () << "s\n" ; std::cout << (s1 + s2).count () << "s\n" ; std::cout << (6 * s1).count () << "s\n" ; std::cout << (s2 / 4 ).count () << "s\n" ; std::cout << std::boolalpha << (s1 < s2) << '\n' ; std::cout << std::boolalpha << (s3 <= s2) << '\n' ; std::cout << std::boolalpha << (s1 > s2) << '\n' ; std::cout << std::boolalpha << (s3 >= s2) << '\n' ; std::cout << std::boolalpha << (s3 == s2) << '\n' ; std::cout << std::boolalpha << (s3 != s2) << '\n' ;
数据类型的转换 如果是没有数据截断(例如小时转分钟)的转换则会通过隐式转换的方式进行转换,如果有数据截断(例如分钟转小时会出现小数,而这部分会被截断),则会编译错误,需要进行显式类型转换。
auto hour = 12 h;auto minute = 90 min;minutes minute2 = hour + minute; hours hour2 = hour + duration_cast <hours>(minute); std::cout << minute2.count () << "min\n" ; std::cout << hour2.count () << "h\n" ;
time_point time_point
有两个模板参数,一个是 clock
(将在后面进行介绍),一个是 duration
。
例如可以定义 1970 年 1 月 1 日之后的 10'000
秒的时间点为
time_point<system_clock, seconds> tp{ 10'000 s };
time_point 可以相减,相减之后得到的是一个 duration。一个 time_point 加上一个 duration 会得到另一个 time_point。
auto d = tp1 - tp2;auto tp2 = tp1 + d;
当存在数据截断时,time_point 也需要进行显示类型转换
time_point<system_clock, seconds> tp{ 5 s }; time_point<system_clock, milliseconds> tp2 = tp; tp = time_point_cast <seconds>(tp2);
可以获取 time_point 到 1970 年 1 月 1 日的时间差
time_point<system_clock, seconds> tp{ 5 s }; seconds s = tp.time_since_epoch (); time_point<system_clock, milliseconds> tp{ 5000 ms }; milliseconds s = tp.time_since_epoch ();
clocks struct some_clock { using duration = chrono::duration<int64_t , microseconds>; using rep = duration::rep; using period = duration::period; using time_point = chrono::time_point<some_clock>; static constexpr bool is_steady = false ; static time_point now () noexcept ; };
每一个 time_point 都关联一个时钟(clocks),不同类型的时钟不能相互转换。
两个常用的时钟
std::chrono::system_clock std::chrono::steady_clock
system_clock 和日历中的时间相关,它可以让你知道是哪一天。steady_clock 通常用于计时。
每个系统时钟都能够获取一个当前时间
clck::time_point tp = clock::now ();
实例 auto t0 = steady_clock::now ();f (); auto t1 = steady_clock::now ();std::cout << nanoseconds{ t1 - t0 }.count () << "ns\n" ;
对时间加锁
std::timed_mutex mut; if (mut.try_lock_for (500 ms)) if (mut.try_lock_until (steady_clock::now () + 500 ms))
自定义时间
using days = duration<int , std::ratio_multiply<std::ratio<24 >, hours::period>>;using days = duration<int , std::ratio<86400 >>;
duration 用于休眠
std::this_thread::sleep_for (days{1 }); std::this_thread::sleep_for (50 s);
计算当前时间到 1970 年 1 月 1 日的秒数和天数
auto tp = time_point_cast <seconds>(system_clock::now ()); cout << tp.time_since_epoch ().count () << "s\n" ; auto td = time_point_cast <days>(tp); cout << td.time_since_epoch ().count () << " days\n" ;