最可靠方法是用 std::chrono::microseconds::count() 获取整型微秒数,再对 1000000 取模得微秒字段;秒字段用总微秒数除以 1000000 后对 60 取模;格式化必须用 %02d 和 %06d 补零,禁用 to_string。

用 std::chrono 提取微秒部分最可靠
直接对原始微秒数取模 1000000 得到微秒字段(SS.uuuuuu 中的 uuuuuu)看似简单,但容易忽略时区、闰秒、系统时钟精度不一致等问题。C++ 标准库中 std::chrono::duration 是唯一能无歧义表达“纯微秒跨度”的类型,应优先用它做拆分。
关键点:
-
std::chrono::microseconds是整型 duration,支持.count()安全转为long long - 用
% 60得秒数(SS),再用% 1000000得微秒余数(uuuuuu),两者必须同源计算,避免浮点截断误差 - 不要用
time_t或struct timeval做中间转换——它们的分辨率可能不足或带符号溢出风险
格式化输出时补零必须手动控制
C++20 的 std::format 尚未普及,且旧版 std::ostringstream 默认不补前导零,std::setfill('0') 容易漏掉字段宽度设置,导致 5.123 变成 5.123 而非 5.000123。
安全做法:
立即学习“C++免费学习笔记(深入)”;
- 秒数用
std::format("{:02d}", ss)(C++20)或printf("%02d", ss) - 微秒部分必须用
std::format("{:06d}", us)或sprintf(buf, "%06d", us)——us是 0–999999 的整数,6 位固定宽度 - 禁止用
std::to_string(us)拼接,它不补零,7会变成"7",不是"000007"
跨平台要注意 std::chrono::steady_clock 和 system_clock 的语义差异
如果你的微秒数来自计时器(如性能测量),必须用 std::chrono::steady_clock;如果来自真实时间戳(如日志打点),才用 std::chrono::system_clock。混用会导致 SS 字段跳变或负值。
常见错误场景:
- 用
steady_clock::now().time_since_epoch()得到的微秒数,直接当成“挂钟时间”去算SS——这是错的,steady_clock不保证从午夜开始计数 - 在 Windows 上用
GetTickCount64()转微秒后套用system_clock逻辑 ——两者起点不同,结果不可比 - Linux 下
clock_gettime(CLOCK_MONOTONIC, ...)返回纳秒,除以 1000 得微秒时未检查是否整除,导致舍入误差
示例:完整可运行的 C++17 兼容写法
以下代码不依赖 C++20,适用于所有主流编译器:
#include <chrono>
#include <iostream>
#include <cstdio>
std::string format_us(long long total_us) {
const auto ss = (total_us / 1000000) % 60; // 秒字段,取模防溢出
const auto us_part = total_us % 1000000; // 微秒余数,0–999999
char buf[16];
std::sprintf(buf, "%02d.%06d", static_cast<int>(ss), static_cast<int>(us_part));
return std::string(buf);
}
// 使用示例:
// auto now = std::chrono::system_clock::now();
// auto us = std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch()).count();
// std::cout << format_us(us) << "\n"; // 输出类似 "42.123456"
注意:total_us 必须是单调递增的整数,不能是浮点近似值;sprintf 中强制转 int 是因 std::sprintf 对 long long 的格式符在旧 libc 上不统一,而 us_part 和 ss 都在 int 范围内。
最易被忽略的是:微秒字段必须严格六位,哪怕原始值是 0 ——0.0 和 0.000000 在协议解析、日志对齐、时序比对中意义完全不同。


















