使用C++11 Chrono库生成含日期、时间及毫秒的时间戳字符串
我来帮你搞定这个用纯Chrono库生成高精度时间戳的需求!
用C++ Chrono库实现"YYYY-MM-DD HH:MM:SS.mmm"格式时间戳
方案一:C++20及以上(推荐,最简洁)
如果你已经升级到C++20,std::format直接支持Chrono时间点的格式化,代码超级简洁,完全不需要依赖旧的time_t或localtime系列函数:
#include <chrono> #include <format> #include <string> std::string get_time_stamp() { // 获取当前系统时间点 const auto now = std::chrono::system_clock::now(); // 提取毫秒部分(取模1000得到0-999的数值) const auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000; // 直接格式化,格式符和strftime类似,毫秒单独补零到三位 return std::format("{:%Y-%m-%d %H:%M:%S}.{:03d}", now, ms.count()); }
这段代码的优势在于:
- 完全基于现代Chrono库,没有旧API的安全警告
std::format的格式字符串可读性极强,出错概率低- 自动处理日期时间字段的补零(比如月份、日期小于10时自动加前导零)
方案二:C++11/14/17(兼容旧标准)
如果你的项目还在使用C++20之前的标准,我们可以结合Chrono获取高精度时间,再用安全的本地时间转换函数替代localtime,同时避免不安全警告:
#include <chrono> #include <string> #include <cstdio> #include <ctime> std::string get_time_stamp() { char buf[50] = {0}; // 获取当前系统时间点 const auto now = std::chrono::system_clock::now(); // 转换为time_t(仅用于提取日期时间字段,毫秒部分由Chrono直接获取) const auto time_now = std::chrono::system_clock::to_time_t(now); // 安全的本地时间转换:MSVC用localtime_s,GCC/Clang用localtime_r std::tm tm_now{}; #ifdef _MSC_VER // MSVC的localtime_s参数顺序是:tm指针在前,time_t指针在后 localtime_s(&tm_now, &time_now); #else // GCC/Clang的localtime_r参数顺序相反 localtime_r(&time_now, &tm_now); #endif // 提取毫秒部分 const auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000; // 格式化字符串,手动补零确保格式正确 std::snprintf(buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d:%02d.%03d", tm_now.tm_year + 1900, // tm_year是从1900年开始的偏移量,需要加1900 tm_now.tm_mon + 1, // tm_mon从0开始(0=1月),需要加1 tm_now.tm_mday, tm_now.tm_hour, tm_now.tm_min, tm_now.tm_sec, static_cast<int>(ms.count())); return std::string(buf); }
关于你提到的MSVC没有localtime_s的疑问
其实MSVC是支持localtime_s的,它是微软为替代不安全的localtime提供的安全函数,需要注意:
- 必须包含
<ctime>头文件 - 参数顺序和
localtime_r相反:第一个参数是std::tm*,第二个是const time_t*
这样写的代码既用到了Chrono的高精度时间能力,又避免了旧API的安全警告,同时兼容主流编译器。
内容的提问来源于stack exchange,提问作者code_fodder
相关产品推荐
相关产品推荐

