std::chrono 主要包含两部分,std::chrono::duration 和 std::chrono::time_point,它们都是类模板,std::chrono::duration 表示时间间隔,std::chrono::time_point 表示时间中的一个点。
template <class Rep, class Period = std::ratio<1>>
class duration;
duration 由 Rep 类型的计次数和计次周期组成,其中计次周期是一个编译期有理数常量,表示从一个计次到下一个的秒数。
存储于 duration 的数据仅有 Rep 类型的计次数。若 Rep 是浮点数,则 duration 能表示小数的计次数。 Period 被包含为时长类型的一部分,且只在不同时长间转换时使用。
template <std::intmax_t Num, std::intmax_t Denom = 1>
class ratio;
ratio 表示值等于 Num/Denom 的有理数,它的静态数据成员 num 与 den 表示由 Num 与 Denom 除以其最大公约数的分子与分母。
duration 有一些便利类型定义:
类型 | 定义 |
---|---|
std::chrono::nanoseconds | duration*至少 64 位的有符号整数类型*/, std::nano> |
std::chrono::microseconds | duration*至少 55 位的有符号整数类型*/, std::micro> |
std::chrono::milliseconds | duration*至少 45 位的有符号整数类型*/, std::milli> |
std::chrono::seconds | duration*至少 35 位的有符号整数类型*/> |
std::chrono::minutes | duration*至少 29 位的有符号整数类型*/, std::ratio<60>> |
std::chrono::hours | duration*至少 23 位的有符号整数类型*/, std::ratio<3600>> |
duration 的概要声明:
template <class Rep, class Period = ratio<1>>
class duration {
public:
using rep = Rep;
using period = Period;
public:
// 构造/复制/销毁
constexpr duration() = default;
template <class Rep2>
constexpr explicit duration(const Rep2& r);
template <class Rep2, class Period2>
constexpr duration(const duration<Rep2, Period2>& d);
~duration() = default;
duration(const duration&) = default;
duration& operator=(const duration&) = default;
// 探察函数
constexpr rep count() const;
// 特殊值
static constexpr duration zero();
static constexpr duration min();
static constexpr duration max();
};
不同时长间转换时,如果转换不损失精度,可以使用 std::duration 的构造函数进行转换,否则要用以下函数进行转换:
template <class ToDuration, class Rep, class Period>
constexpr ToDuration duration_cast(const duration<Rep, Period>& d);
duration 的一个例子:
#include
#include
constexpr auto year = 31556952ll; // 格里高利历年的平均秒数
int main()
{
using shakes = std::chrono::duration<int, std::ratio<1, 100000000>>;
using jiffies = std::chrono::duration<int, std::centi/*std::ratio<1, 100>*/>;
using weeks = std::chrono::duration<float, std::ratio<7*24*60*60>>;
using nanocenturies = std::chrono::duration<float, std::ratio<100*year, 1000000000>>;
std::chrono::seconds sec(1);
std::cout << "1 second is:\n";
// 无精度损失的整数尺度转换:无转型
std::cout << std::chrono::microseconds(sec).count() << " microseconds\n"
<< shakes(sec).count() << " shakes\n"
<< jiffies(sec).count() << " jiffies\n";
// 有精度损失的整数尺度转换:需要转型
std::cout << std::chrono::duration_cast<std::chrono::minutes>(sec).count()
<< " minutes\n";
// 浮点尺度转换:无转型
std::cout << weeks(sec).count() << " weeks\n"
<< nanocenturies(sec).count() << " nanocenturies\n";
}
template <class Clock, class Duration = typename Clock::duration>
class time_point;
time_point 被实现成如同存储一个 Duration 类型的自 Clock 的纪元起始开始的时间间隔的值。
Clock 必须满足 时钟 (Clock) 的要求,库提供了三种 Clock:
class | description |
---|---|
system_clock | 来自系统范畴实时时钟的挂钟时间 |
steady_clock | 决不会调整的单调时钟 |
high_resolution_clock | 拥有可用的最短嘀嗒周期的时钟 |
其中 system_clock 的概要声明:
class system_clock {
public:
using rep = /* 见说明 */ ;
using period = ratio</* 未指明 */, /* 未指明 */ >;
using duration = chrono::duration<rep, period>;
using time_point = chrono::time_point<system_clock>;
static constexpr bool is_steady = /* 未指明 */ ;
static time_point now() noexcept;
// 以上是Clock必须满足的要求
static time_t to_time_t (const time_point& t) noexcept;
static time_point from_time_t(time_t t) noexcept;
};
time_point 的概要声明:
template <class Clock, class Duration = typename Clock::duration>
class time_point {
public:
using clock = Clock;
using duration = Duration;
using rep = typename duration::rep;
using period = typename duration::period;
public:
// 构造
constexpr time_point(); // 拥有纪元值
constexpr explicit time_point(const duration& d); // 同 time_point() + d
template <class Duration2>
constexpr time_point(const time_point<clock, Duration2>& t);
// 探察函数
constexpr duration time_since_epoch() const;
// 算术
constexpr time_point& operator+=(const duration& d);
constexpr time_point& operator-=(const duration& d);
// 特殊值
static constexpr time_point min();
static constexpr time_point max();
};
time_point_cast 用于同一 clock 下一个 time point 向另一个 time point 的转换:
template <class ToDuration, class Clock, class Duration>
constexpr time_point<Clock, ToDuration>
time_point_cast(const time_point<Clock, Duration>& t);
time_point 的一个例子:
#include
#include
#include
using Ms = std::chrono::milliseconds;
using Sec = std::chrono::seconds;
template <class Duration>
using TimePoint = std::chrono::time_point<std::chrono::high_resolution_clock, Duration>;
inline void print_ms(const TimePoint<Ms>& time_point)
{
std::cout << time_point.time_since_epoch().count() << " ms\n";
}
int main()
{
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
std::time_t now_c = std::chrono::system_clock::to_time_t(now - std::chrono::hours(24));
std::cout << "24 hours ago, the time was " << std::ctime(&now_c) << '\n';
TimePoint<Sec> time_point_sec(Sec(4));
// 隐式转换,无精度损失
TimePoint<Ms> time_point_ms(time_point_sec);
print_ms(time_point_ms); // 4000 ms
time_point_ms = TimePoint<Ms>(Ms(5756));
// 显式转型,在精度损失可能发生时需要
// 5756 truncated to 5000
time_point_sec = std::chrono::time_point_cast<Sec>(time_point_ms);
print_ms(time_point_sec); // 5000 ms
}
以上主要参考自 cppreference。