必须用 std::chrono::system_clock::now() 获取时间点,再用 duration_cast 和取模提取毫秒,最后用 strftime 或 std::format 拼接秒与补零毫秒。

如何用 std::chrono 获取带毫秒的当前时间
直接用 std::time() 或 std::localtime() 拿不到毫秒——它们只到秒级。必须用 std::chrono::system_clock 配合 std::chrono::milliseconds 截断或舍入。
关键不是“格式化”,而是“先拿到毫秒精度的时间点”。常见错误是用 std::chrono::steady_clock,它不对应日历时间,不能转成可读字符串;必须用 system_clock。
-
auto now = std::chrono::system_clock::now();获取高精度时间点 -
auto ms = std::chrono::duration_cast<:chrono::milliseconds>(now.time_since_epoch()) % 1000;</:chrono::milliseconds>提取毫秒部分(注意是模 1000) -
auto sec = std::chrono::time_point_cast<:chrono::seconds>(now);</:chrono::seconds>得到整秒时间点,再转std::time_t用于std::strftime
用 std::strftime 格式化时分秒 + 毫秒
std::strftime 本身不支持毫秒占位符(比如 %f 是非标准扩展,MSVC 不认,GCC/Clang 在 strftime 中也不可靠),所以不能指望一行搞定。得手动拼接。
典型做法:先用 strftime 格式化到秒,再补上三位毫秒数字。
立即学习“C++免费学习笔记(深入)”;
- 秒级部分:用
std::strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm) - 毫秒部分:用
std::sprintf或std::to_string(ms.count()),但要注意补零(ms是int,值域 0–999) - 推荐补零写法:
printf("%03d", ms.count())或std::format("{:03}", ms.count())(C++20)
C++20 std::format 能否一行输出带毫秒的时间?
可以,但要注意兼容性和陷阱。C++20 的 std::format 支持 {:%Y-%m-%d %H:%M:%S},但依然不支持毫秒直接格式化(%f 不在标准规范里)。
你仍然得拆开处理:先格式化秒,再单独格式化毫秒,最后拼接。不过 std::format 让拼接更干净:
auto now = std::chrono::system_clock::now();
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;
auto sec = std::chrono::time_point_cast<std::chrono::seconds>(now);
std::string s = std::format("{:%Y-%m-%d %H:%M:%S}.{:03}", sec, ms.count());
注意:std::format 在 GCC 13+、Clang 15+ 才稳定支持;MSVC 从 19.35 开始部分支持,但需开启 /std:c++20 且链接 stdc++fs(某些版本)。
为什么 gettimeofday() 或 clock_gettime() 不推荐?
这些 C API 虽然能拿到毫秒甚至微秒,但跨平台差:Windows 没 gettimeofday,clock_gettime 在 macOS 上不支持 CLOCK_REALTIME(得用 mach_absolute_time),维护成本高。
除非你在写系统级工具且明确锁定 Linux,否则优先用 std::chrono::system_clock——它是 C++ 标准保证的、跨平台的、能映射到日历时间的时钟。
容易被忽略的一点:system_clock::now() 的实际精度取决于系统,Windows 上通常只有 10–15ms,Linux 通常能到 1ms;别假设它总能返回真·毫秒级时间戳,尤其在虚拟机里。


















