在C++的标准库中,std::chrono::duration是用于表示时间间隔的核心类型,它可以配合std::chrono::time_point完成两个时间点之间时差的计算,同时支持不同时间单位之间的灵活转换,能够满足高精度时间统计的需求。

std::chrono::duration基础概念
std::chrono::duration是一个模板类,定义形式为template<class Rep, class Period = std::ratio<1>> class duration;,其中Rep是存储时间计数的数值类型,通常是整数或浮点数;Period是表示时间单位的std::ratio类型,用来定义每个计数对应的实际时间长度。
标准库已经预定义了很多常用的duration类型:
std::chrono::hours:小时,Period为std::ratio<3600>std::chrono::minutes:分钟,Period为std::ratio<60>std::chrono::seconds:秒,Period为std::ratio<1>std::chrono::milliseconds:毫秒,Period为std::ratio<1, 1000>std::chrono::microseconds:微秒,Period为std::ratio<1, 1000000>std::chrono::nanoseconds:纳秒,Period为std::ratio<1, 1000000000>
计算两个时间点的时差
要计算时差,首先需要获取两个时间点,然后通过时间点相减得到duration对象。时间点的获取通常使用std::chrono::steady_clock或者std::chrono::system_clock的now()方法,其中steady_clock是单调时钟,更适合计算时间间隔,不会受到系统时间调整的影响。
下面是计算时差的基础示例:
#include <iostream>
#include <chrono>
#include <thread>
int main() {
// 获取开始时间点
auto start = std::chrono::steady_clock::now();
// 模拟一段耗时操作,休眠1.5秒
std::this_thread::sleep_for(std::chrono::milliseconds(1500));
// 获取结束时间点
auto end = std::chrono::steady_clock::now();
// 两个时间点相减得到duration对象,默认单位是steady_clock的时钟周期
std::chrono::duration<double> elapsed = end - start;
// 输出默认的秒数结果
std::cout << "耗时(秒): " << elapsed.count() << std::endl;
return 0;
}
上述代码中,end - start的操作会返回一个std::chrono::steady_clock::duration类型的对象,该对象的count()方法可以返回对应的计数值,不过直接输出的数值单位是时钟的周期,通常没有实际意义,需要转换为常用的时间单位。
时间间隔的单位转换
duration之间可以通过std::chrono::duration_cast模板进行显式转换,将获取到的时间间隔转换为我们需要的时间单位。比如将纳秒级的duration转换为毫秒、秒等单位。
单位转换的示例代码如下:
#include <iostream>
#include <chrono>
#include <thread>
int main() {
auto start = std::chrono::steady_clock::now();
// 模拟耗时操作
std::this_thread::sleep_for(std::chrono::milliseconds(1234));
auto end = std::chrono::steady_clock::now();
// 获取原始的duration对象
auto elapsed_raw = end - start;
// 转换为不同的时间单位
auto elapsed_ms = std::chrono::duration_cast<std::chrono::milliseconds>(elapsed_raw);
auto elapsed_s = std::chrono::duration_cast<std::chrono::seconds>(elapsed_raw);
auto elapsed_us = std::chrono::duration_cast<std::chrono::microseconds>(elapsed_raw);
std::cout << "耗时(毫秒): " << elapsed_ms.count() << std::endl;
std::cout << "耗时(秒): " << elapsed_s.count() << std::endl;
std::cout << "耗时(微秒): " << elapsed_us.count() << std::endl;
return 0;
}
需要注意的是,当从高精度单位转换为低精度单位时,会发生截断,比如上述例子中1234毫秒转换为秒会得到1秒,丢失了234毫秒的部分。如果需要保留小数部分,可以使用浮点数类型的duration作为转换目标:
#include <iostream>
#include <chrono>
#include <thread>
int main() {
auto start = std::chrono::steady_clock::now();
std::this_thread::sleep_for(std::chrono::milliseconds(1234));
auto end = std::chrono::steady_clock::now();
auto elapsed_raw = end - start;
// 转换为浮点秒数,保留小数部分
auto elapsed_s_float = std::chrono::duration_cast<std::chrono::duration<double>>(elapsed_raw);
std::cout << "耗时(浮点秒): " << elapsed_s_float.count() << std::endl;
return 0;
}
自定义duration类型
除了使用标准库预定义的duration类型,我们还可以根据自己的需求自定义duration,比如定义一个表示1/30秒的类型,适用于帧率统计场景:
#include <iostream>
#include <chrono>
// 自定义duration,30分之一秒为单位
using frame_duration = std::chrono::duration<int, std::ratio<1, 30>>;
int main() {
// 假设统计60帧的耗时
frame_duration frames(60);
// 转换为毫秒
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(frames);
std::cout << "60帧对应的毫秒数: " << ms.count() << std::endl;
return 0;
}
注意事项
- 计算时间间隔优先使用
std::chrono::steady_clock,避免使用system_clock,因为system_clock的时间可能会被用户或系统调整,导致时差计算不准确。 - 不同duration类型之间的转换必须使用
std::chrono::duration_cast,不能直接赋值,否则会出现编译错误。 - duration的count()方法返回的是存储的计数值,不是实际的时间长度,实际时间长度需要结合Period来计算,比如milliseconds的count()返回的是毫秒数,而seconds的count()返回的是秒数。
- 如果需要在不同函数之间传递时间间隔,建议传递原始的duration对象,而不是转换后的数值,这样可以保留时间精度,在需要使用的时候再转换为对应的单位。
std::chrono::duration时差计算时间间隔转换C++修改时间:2026-07-05 14:21:23