如何用chrono将微秒级纪元时间转换为日期字符串
解决chrono微秒级纪元时间转日期字符串的问题
问题原因
ctime 函数的参数要求是指向 time_t 类型的指针,而 time_t 本质是从Unix纪元开始的秒数。当你传入微秒级的计数值时,这个数值是实际秒数的100万倍,ctime 会将其当作秒数解析,自然得到完全错误的日期。
解决方案
方案1:仅需日期字符串(丢弃微秒)
如果不需要保留微秒精度,只需将微秒级时长先转换为秒级,再传入ctime:
auto micro_epoch = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()); // 将微秒转换为秒级time_t std::time_t sec_epoch = std::chrono::duration_cast<std::chrono::seconds>(micro_epoch).count(); std::cout << "Date string = " << std::ctime(&sec_epoch);
方案2:保留微秒精度的日期字符串(C++11+)
如果需要显示微秒,可结合std::put_time和字符串流来格式化:
#include <iostream> #include <chrono> #include <iomanip> #include <sstream> int main() { auto now = std::chrono::system_clock::now(); // 转换为time_t获取日期时间的秒级部分 std::time_t now_time = std::chrono::system_clock::to_time_t(now); // 提取微秒部分(取模1000000得到秒后的微秒数) auto micros_part = std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch()) % 1000000; std::ostringstream oss; // 格式化日期时间的秒级部分 oss << std::put_time(std::localtime(&now_time), "%Y-%m-%d %H:%M:%S"); // 追加微秒,补前导零保证6位 oss << "." << std::setw(6) << std::setfill('0') << micros_part.count(); std::cout << "带微秒的日期字符串:" << oss.str() << std::endl; return 0; }
方案3:更简洁的C++20实现
C++20引入了std::chrono::format,可以直接格式化chrono时间点,无需手动拆分秒和微秒:
#include <iostream> #include <chrono> int main() { auto now = std::chrono::system_clock::now(); // %6f表示保留6位微秒 std::cout << "带微秒的日期字符串:" << std::chrono::format("%Y-%m-%d %H:%M:%S.%6f", now) << std::endl; return 0; }
注意:
std::localtime不是线程安全函数,如果是多线程环境,可使用POSIX标准的std::localtime_r替代,或者依赖编译器提供的线程安全扩展。
内容的提问来源于stack exchange,提问作者xyf
相关产品推荐
相关产品推荐

