You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何更简洁地用毫秒、小时表示C++时长并适配fmt库?

问题:简化C++ chrono时长单位表示并适配fmt库

给定以下用于打印毫秒和小时单位时长的C++代码:

#include <iostream>
#include <chrono>
#include <thread>

using namespace std;
using namespace std::chrono;

int main() {
  auto t0 = high_resolution_clock::now();
  this_thread::sleep_for(300ms);
  auto t1 = high_resolution_clock::now();
  cout << duration<float, milli>{t1-t0}.count() << "\n";
  cout << duration<float, ratio<3600>>{t1-t0}.count() << "\n";
}

需求:

  1. 用更简洁的写法替代繁琐的ratio<3600>,希望直接使用包含hour的写法
  2. 让方案适配fmt库,解决t1-t0无法直接用于fmt的问题
  3. 理解为何duration<float, hour>不能像duration<float, milli>那样使用

解答

1. 为何duration<float, hour>报错?

std::chrono::hour是一个完整的duration类型别名(定义为duration<long long, ratio<3600>>),而duration模板的第二个参数需要的是ratio类型(比如milli是ratio<1,1000>的别名),不是完整的duration类型。因此直接写duration<float, hour>会触发模板参数不匹配的错误,正确的做法是用hour对应的ratio——hours::period。

2. 简化时长单位的写法

可以利用标准库预定义的时间单位别名,结合直接构造对应浮点类型的duration,避免手动写ratio<3600>:

方法1:直接使用预定义period构造浮点duration

// 替代ratio<3600>,用hours::period获取小时对应的ratio
cout << duration<float, hours::period>{t1 - t0}.count() << " hours\n";
// 毫秒的写法可以保持不变,或者统一风格
cout << duration<float, milliseconds::period>{t1 - t0}.count() << " ms\n";

方法2:自定义浮点时间单位别名(更简洁)

提前定义常用的浮点时间单位,代码可读性更高:

using float_milliseconds = std::chrono::duration<float, std::chrono::milliseconds::period>;
using float_hours = std::chrono::duration<float, std::chrono::hours::period>;

// 使用时直接转换
cout << float_milliseconds{t1 - t0}.count() << " ms\n";
cout << float_hours{t1 - t0}.count() << " hours\n";

3. 适配fmt库的方案

fmt库从版本9开始支持std::chrono类型的格式化,只需包含<fmt/chrono.h>,无需手动调用count(),还能直接指定输出格式:

完整示例代码

#include <iostream>
#include <chrono>
#include <thread>
#include <fmt/chrono.h>

using namespace std;
using namespace std::chrono;

// 自定义浮点时间单位别名(可选)
using float_milliseconds = duration<float, milliseconds::period>;
using float_hours = duration<float, hours::period>;

int main() {
  auto t0 = high_resolution_clock::now();
  this_thread::sleep_for(300ms);
  auto t1 = high_resolution_clock::now();
  auto elapsed = t1 - t0;

  // 标准iostream输出
  cout << float_milliseconds{elapsed}.count() << " ms\n";
  cout << float_hours{elapsed}.count() << " hours\n";

  // fmt库输出(直接格式化duration,支持多种格式)
  fmt::print("fmt输出(自动单位):{}\n", elapsed);
  fmt::print("fmt输出(显式毫秒):{:.2f} ms\n", float_milliseconds{elapsed});
  fmt::print("fmt输出(显式小时):{:.6f} hours\n", float_hours{elapsed});
}

关键说明

  • 必须包含<fmt/chrono.h>才能让fmt支持chrono类型
  • fmt支持直接格式化std::chrono::duration对象,也支持格式化转换后的浮点duration类型
  • 可以通过格式字符串指定精度和单位,比如{:.2f} ms控制保留两位小数

内容的提问来源于stack exchange,提问作者Paul Jurczak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 14:23:13