C++ 支持两种类型的时间操作:
- Chrono库,在chrono头文件中提供
- C 风格日期和时间库,std::time这种,在ctime头文件中提供
chrono库
在<chrono>
中,标准库提供了处理时间段和时间点的组件:
- clocks
- time points
- durations
在C++20以后提供: - calendar dates
- time zone information
duration
- 定义一个具有指定period的duration:
template<
class Rep,
class Period = std::ratio<1>
> class duration;
其中Rep表示一个算术类型,用于表示时钟ticks数;Period表示一个时钟tick周期(可以理解为一个tick多少秒),这里是一个std::ratio
值,默认为std::ratio<1>
。
关于std::ratio
,可以理解为Num/Denom
template<
std::intmax_t Num,
std::intmax_t Denom = 1
> class ratio;
具体例子:
duration<long long, std::milli> d1{7}; // 7ms
std::cout << d1.count() << std::endl;
time_point
标准库提供了time_point,用来表示给定纪元的一个时间点,用给定的clock度量。一个纪元(epoch)就是由给定clock确定的一个时间范围,用duration来衡量,从duration::zero()
开始。
template<
class Clock,
class Duration = typename Clock::duration
> class time_point;
clocks
在chrono中,标准库提供了基本的时钟接口。系统提供了3个命名的时钟:
- system_clock
系统实时时钟,可以重置系统时钟(向前或者向后跳)来匹配内部时钟 - steady_clock
时间稳定推移的时钟,即时间不会回退且时钟周期的间隔是常量 - high_resolution_clock
一个系统上具有最短时间增量的时钟‘
这三个时钟有可能只是相同时钟的别名,这个跟不同系统不同实现有关,通过下面这种方式,可以获取系统上不同时钟的属性:
std::cout << "min: " << std::chrono::system_clock::duration::min().count()
<< ",max: " << std::chrono::system_clock::duration::max().count()
<< ","
<< (std::chrono::treat_as_floating_point<
std::chrono::system_clock::duration>::value
? "FP"
: "integral")
<< std::endl;
std::cout << "min: " << std::chrono::steady_clock::duration::min().count()
<< ",max: " << std::chrono::steady_clock::duration::max().count()
<< ","
<< (std::chrono::treat_as_floating_point<
std::chrono::steady_clock::duration>::value
? "FP"
: "integral")
<< std::endl;
std::cout << "min: "
<< std::chrono::high_resolution_clock::duration::min().count()
<< ",max: "
<< std::chrono::high_resolution_clock::duration::max().count()
<< ","
<< (std::chrono::treat_as_floating_point<
std::chrono::high_resolution_clock::duration>::value
? "FP"
: "integral")
<< std::endl;
在我的系统上,他们的输出是一样的。
可以通过对system_clock、steady_clock和high_resolution_clock这3种时钟之一调用now()获取当前的时间点,时间点之间的距离就是时间段:
std::chrono::time_point<std::chrono::system_clock> t =
std::chrono::system_clock::now();
std::cout << t.time_since_epoch().count() << std::endl;
for (int i = 0; i < 10000; i++) { ; }
std::chrono::system_clock::duration d =
std::chrono::system_clock::now() - t;
std::cout << d.count() << std::endl;
C 风格日期和时间库
是C语言<time.h>头文件的C++版本,提供了C风格的时间。
提供的一些内容基本如下:
#define NULL /* see description */
#define CLOCKS_PER_SEC /* see description */
#define TIME_UTC /* see description */
namespace std {
using size_t = /* see description */;
using clock_t = /* see description */;
using time_t = /* see description */;
struct timespec;
struct tm;
clock_t clock();
double difftime(time_t time1, time_t time0);
time_t mktime(tm* timeptr);
time_t time(time_t* timer);
int timespec_get(timespec* ts, int base);
char* asctime(const tm* timeptr);
char* ctime(const time_t* timer);
tm* gmtime(const time_t* timer);
tm* localtime(const time_t* timer);
size_t strftime(char* s, size_t maxsize, const char* format, const tm* timeptr);
}
例子:
// 获取当前时间
std::time_t t = std::time(nullptr);
std::cout << std::asctime(std::localtime(&t)) << std::ctime(&t) << t
<< " seconds since the Epoch\n";
// 计算操作时间间隔
const std::time_t tt_start = std::time(nullptr);
const std::clock_t c_start = std::clock();
auto t_start = std::chrono::high_resolution_clock::now();
// 操作开始
for (int i = 0; i < 10000; i++) { ; }
// 操作结束
const std::time_t tt_end = std::time(nullptr);
const std::clock_t c_end = std::clock();
const auto t_end = std::chrono::high_resolution_clock::now();
// 计算时间间隔
std::cout
<< std::fixed << std::setprecision(2)
<< "CPU time used: " << 1000.0 * (c_end - c_start) / CLOCKS_PER_SEC
<< "ms\n"
<< std::difftime(tt_end, tt_start) << "s\n"
<< "Wall clock time passed: "
<< std::chrono::duration<double, std::milli>(t_end - t_start).count()
<< "ms\n"
<< std::endl;