最常用方式是调用std::chrono::system_clock::now()获取time_point,再通过to_time_t()转为time_t才能格式化输出;直接打印time_point会导致编译失败或无意义数值。

用 std::chrono::system_clock 获取当前系统时间(秒级精度)
最常用也最直接的方式是调用 std::chrono::system_clock::now(),它返回一个 time_point,代表自纪元(通常是 1970-01-01 00:00:00 UTC)以来的时间。注意:这个值本身不是“可读时间”,要转成 time_t 才能用 std::ctime 或 std::strftime 格式化。
常见错误是直接打印 time_point 对象,结果是编译失败或输出无意义的数值(比如纳秒计数)。
- 正确做法:先用
.time_since_epoch().count()查看底层计数值(调试用),但生产中应转为time_t - 转换关键函数:
std::chrono::system_clock::to_time_t() - 示例:
auto now = std::chrono::system_clock::now(); std::time_t t = std::chrono::system_clock::to_time_t(now); std::cout << std::ctime(&t); // 输出类似 "Wed Apr 10 15:23:41 2024\n"
获取毫秒/微秒级时间戳(避免 std::time() 精度不足)
std::time() 只能到秒,而 std::chrono 支持更高精度。关键是选择合适的时间单位并做类型转换——别直接用 auto 接转换结果,否则可能丢失精度或触发隐式截断。
- 推荐写法:
auto ms = std::chrono::duration_cast<:chrono::milliseconds>(now.time_since_epoch()).count(); - 不要写:
auto ms = now.time_since_epoch().count();—— 这里count()返回的是纳秒(取决于实现),不是毫秒 - 微秒同理:
std::chrono::duration_cast<:chrono::microseconds>(...) - 注意:Windows 上
system_clock实际精度可能只有 10–15ms,别指望真达到纳秒级
跨平台格式化本地时间(避开 localtime_s / localtime_r 差异)
C++20 引入了 的日历支持,但 C++11/14/17 没有。所以目前最稳妥的做法仍是用 C 风格函数,但得处理好线程安全和平台差异:
立即学习“C++免费学习笔记(深入)”;
- Linux/macOS:用
localtime_r(&t, &tm),tm是栈上变量 - Windows:用
localtime_s(&tm, &t),参数顺序相反 - 更简单的替代:用
std::put_time(C++11 起)配合std::localtime(不推荐多线程环境) - 示例(单线程安全):
auto now = std::chrono::system_clock::now(); std::time_t t = std::chrono::system_clock::to_time_t(now); std::cout << std::put_time(std::localtime(&t), "%Y-%m-%d %H:%M:%S");
为什么不用 std::chrono::steady_clock?
steady_clock 是单调时钟,适合测间隔(比如性能计时),但它不对应系统时间——不能转成 time_t,也没有 to_time_t 方法。一旦你看到代码里用 steady_clock::now() 去“获取当前日期”,那基本就是逻辑错误。
- 典型误用:
std::chrono::steady_clock::to_time_t(...)→ 编译失败 - 正确分工:
system_clock用于时间点(日志、时间戳),steady_clock用于持续时间(超时、耗时统计) - 如果需要高精度且带时区的当前时间,C++20 的
zoned_time更合适,但目前主流编译器支持仍有限
nanoseconds 就真能拿到纳秒,结果在 Windows 上跑出来全是 15ms 的倍数;还有人把 steady_clock 和系统时间混用,导致日志时间戳突然倒退或跳变。











