包含的头文件
#include <chrono>
命名空间
std::chrono
涉及类
chrono 库定义三种主要类型以及工具函数和常用 typedef 。
时钟
时钟由起点(或纪元)及计次频率组成。例如,时钟可以拥有 1970 年 1 月 1 日的纪元,和每一秒的计次。 C++ 定义数种时钟类型:
std::chrono::system_clock
std::chrono::steady_clock (不做具体说明,可参照上述system_clock)
三个静态成员函数
1. now
2. to_time_t
3. from_time_t
(1) now()函数
可用于获取当前时间戳
static std::chrono::time_point<std::chrono::system_clock> now() noexcept; | | (C++11 起) |
返回表示当前时间的时间点。 参照头文件中定义可知该函数声明展开应该是:
static std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> now() noexcept();?
struct system_clock
{
typedef chrono::nanoseconds duration;
typedef duration::rep rep;
typedef duration::period period;
typedef chrono::time_point<system_clock, duration> time_point;
static_assert(system_clock::duration::min()
< system_clock::duration::zero(),
"a clock's minimum duration cannot be less than its epoch");
static constexpr bool is_steady = false;
static time_point
now() noexcept;
// Map to C API
static std::time_t
to_time_t(const time_point& __t) noexcept
{
return std::time_t(duration_cast<chrono::seconds>
(__t.time_since_epoch()).count());
}
static time_point
from_time_t(std::time_t __t) noexcept
{
typedef chrono::time_point<system_clock, seconds> __from;
return time_point_cast<system_clock::duration>
(__from(chrono::seconds(__t)));
}
};
使用示例:
#include <chrono>
using namespace std::chrono;
system_clock::time_point tp = system_clock::now();
(2) to_time_t() 函数
将时间戳转换成整型数
static std::time_t to_time_t( const time_point& t ) noexcept; | | (C++11 起) | | | |
转换 t 为 std::time_t 类型。
若 std::time_t 拥有较低精度,则是舍入还是截断值是实现定义的。
std::time_t是C风格的表示,可以理解为整数类型值,详细说明见下:
定义于头文件 <ctime> | | | typedef /* 未说明 */ time_t; | | | | | |
足以表示时间的算术类型。
虽然标准中没有给出定义,但是该类型几乎总是整数类型,表示自 1970 年 1 月 1 日 00:00 UTC 以来所经过的秒数(不计闰秒),对应 POSIX 时间。
(3) from_time_t() 函数
将整型数转换成时间戳time_point
static std::chrono::system_clock::time_point from_time_t( std::time_t t ) noexcept; | | (C++11 起) | | | |
用二个类型间的较低精度,转换 t 为时间点类型。
若 time_point 拥有较低精度,则舍入还是截断值是实现定义的。
时间点
时间点是从特定时钟的纪元开始经过的时间时长。
std::chrono::time_point
成员函数
(1)time_since_epoch
? (2)? ?time_point_cast
类定义
template< ? ? class Clock, ? ? class Duration = typename Clock::duration > class time_point; |
构造该对象时候需要传入两个参数:
(1)Clock
? (2)? ?Duration
可以参考std::chrono::system_clock::time_point定义
typedef chrono::time_point<system_clock, duration> time_point;
typedef chrono::nanoseconds duration;
typedef duration<int64_t, nano> nanoseconds;
typedef ratio<1, 1000000000> nano;
Clock -> system_clock
duration -> chrono::nanoseconds //纳秒
chrono::nanoseconds -> -> std::chrono::duration<int64_t, nano>
nano -> typedef ratio<1, 1000000000> nano;
time_since_epoch 函数
duration time_since_epoch() const; | | (C++11 起) (C++14 前) | constexpr duration time_since_epoch() const; | | (C++14 起) | | | |
返回表示 *this 与 clock 的纪元间的时间量的 duration 。
time_point_cast() 函数
template <class ToDuration, class Clock, class Duration> time_point<Clock, ToDuration> time_point_cast( ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const time_point<Clock, Duration> &t); | | (C++11 起) (C++14 前) | template <class ToDuration, class Clock, class Duration> constexpr time_point<Clock, ToDuration> time_point_cast( ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const time_point<Clock, Duration> &t); | | (C++14 起) | | | |
将 std::chrono::time_point 从一个 duration 到另一个。
上述两个函数结合示例:
auto p1 = std::chrono::system_clock::now();
std::cout << "hours since epoch: "
<< std::chrono::duration_cast<std::chrono::hours>(
p1.time_since_epoch()).count()
时长
时长由时间跨度组成,定义为某时间单位的某个计次数。例如,“ 42 秒”可表示为由 42 个 1 秒时间点位的计次所组成的时长。
std::chrono::duration
成员函数:
(1) count
(2) duration_cast
辅助类型:
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>> |
类定义
template< ? ? class Rep, ? ? class Period = std::ratio<1> > class duration; | | (C++11 起) | | | |
类模板 std::chrono::duration 表示时间间隔。
它由 Rep 类型的计次数和计次周期组成,其中计次周期是一个编译期有理数常量,表示从一个计次到下一个的秒数。
存储于 duration 的数据仅有 Rep 类型的计次数。若 Rep 是浮点数,则 duration 能表示小数的计次数。 Period 被包含为时长类型的一部分,且只在不同时长间转换时使用。
count() 函数
constexpr rep count() const; | | | | | |
返回此 duration 的计次数。
示例:
#include <chrono>
#include <iostream>
int main()
{
std::chrono::milliseconds ms{3}; // 3 毫秒
// 从 3 毫秒构造 6000 微秒
std::chrono::microseconds us = 2*ms;
// 使用分数计次的 30Hz 时钟
std::chrono::duration<double, std::ratio<1, 30>> hz30(3.5);
std::cout << "3 ms duration has " << ms.count() << " ticks\n"
<< "6000 us duration has " << us.count() << " ticks\n"
<< "3.5 30Hz duration has " << hz30.count() << " ticks\n";
duration_cast() 函数
template <class ToDuration, class Rep, class Period> constexpr ToDuration duration_cast(const duration<Rep,Period>& d); | | (C++11 起) | | | |
转换 std::chrono::duration 为不同类型 ToDuration 的时长。
不使用隐式转换。可能的情况下避免乘法和除法,若在编译时已知一或多个参数为 1 。以最宽的可用类型进行计算,而如同用 static_cast 到结果类型的转换,只在完成时进行。
示例:
#include <iostream>
#include <chrono>
#include <ratio>
#include <thread>
void f()
{
std::this_thread::sleep_for(std::chrono::seconds(1));
}
int main()
{
auto t1 = std::chrono::high_resolution_clock::now();
f();
auto t2 = std::chrono::high_resolution_clock::now();
// 整数时长:要求 duration_cast
auto int_ms = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1);
// 小数时长:不要求 duration_cast
std::chrono::duration<double, std::milli> fp_ms = t2 - t1;
std::cout << "f() took " << fp_ms.count() << " ms, "
<< "or " << int_ms.count() << " whole milliseconds\n";
}
总结:目前使用到的C++风格的时间相关函数,只能拿到时间戳,实现的功能很少,实用性较低,且封装成static函数,偏C的风格更多,不是很好~。
|