chrono 标准库
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 = 12h;
minutes minute = 30min;
seconds s = 10s;
milliseconds ms = 100ms;
microseconds us = 200us;
nanoseconds ns = 300ns;
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 = 12h;
auto minute = 30min;
auto s = 10s;
auto ms = 100ms;
auto us = 200us;
auto ns = 300ns;
如何输出时间
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 = 10s;
seconds s2 = 200s;
seconds s3 = 200s;
std::cout << (s2 - s1).count() << "s\n"; // 190s
std::cout << (s1 + s2).count() << "s\n"; // 210s
std::cout << (6 * s1).count() << "s\n"; // 60s
std::cout << (s2 / 4).count() << "s\n"; // 50s
std::cout << std::boolalpha << (s1 < s2) << '\n'; // true
std::cout << std::boolalpha << (s3 <= s2) << '\n'; // true
std::cout << std::boolalpha << (s1 > s2) << '\n'; // false
std::cout << std::boolalpha << (s3 >= s2) << '\n'; // true
std::cout << std::boolalpha << (s3 == s2) << '\n'; // true
std::cout << std::boolalpha << (s3 != s2) << '\n'; // false
数据类型的转换
如果是没有数据截断(例如小时转分钟)的转换则会通过隐式转换的方式进行转换,如果有数据截断(例如分钟转小时会出现小数,而这部分会被截断),则会编译错误,需要进行显式类型转换。
auto hour = 12h;
auto minute = 90min;
minutes minute2 = hour + minute;
hours hour2 = hour + duration_cast<hours>(minute);
std::cout << minute2.count() << "min\n"; // 810min
std::cout << hour2.count() << "h\n"; // 13h
time_point
time_point
有两个模板参数,一个是 clock
(将在后面进行介绍),一个是 duration
。
例如可以定义 1970 年 1 月 1 日之后的 10'000
秒的时间点为
time_point<system_clock, seconds> tp{ 10'000s };
time_point 可以相减,相减之后得到的是一个 duration。一个 time_point 加上一个 duration 会得到另一个 time_point。
auto d = tp1 - tp2;
auto tp2 = tp1 + d;
当存在数据截断时,time_point 也需要进行显示类型转换
time_point<system_clock, seconds> tp{ 5s }; // 5s
time_point<system_clock, milliseconds> tp2 = tp; // 5000ms
tp = time_point_cast<seconds>(tp2); // 5s
可以获取 time_point 到 1970 年 1 月 1 日的时间差
time_point<system_clock, seconds> tp{ 5s }; // 5s
seconds s = tp.time_since_epoch();
time_point<system_clock, milliseconds> tp{ 5000ms }; // 5000ms
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(500ms))
// got the lock
if (mut.try_lock_until(steady_clock::now() + 500ms))
// got the lock
自定义时间
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(50s);
计算当前时间到 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";