最直接方式是用 std::time(nullptr) 获取 time_t 时间戳,再用 std::localtime() 转为 struct tm;但该函数非线程安全、结果存于静态缓冲区,多线程或多次调用会相互覆盖,应改用 localtime_r(POSIX)或 localtime_s(Windows);格式化推荐 std::strftime 而非手动拼接,注意年份需加1900、月份加1;C++20 可用 std::chrono::system_clock::now() 配合 std::format,但兼容性有限,fallback 仍需 strftime;UTC 时间应使用 std::gmtime(),并可用 "%Y-%m-%dT%H:%M:%SZ" 生成 ISO 8601 格式。

用 std::time + std::localtime 获取本地当前日期时间
最直接的方式是调用 C 标准库的 time() 获取秒级时间戳,再用 localtime() 转为可读结构体。注意 localtime() 返回的是 struct tm*,且结果存储在静态缓冲区中,**不可多线程直接共用**。
常见错误:直接对 localtime() 返回值做多次连续调用,后一次会覆盖前一次内容(比如想同时打印“今天”和“明天”的日期)。
-
std::time(nullptr)返回从 1970-01-01 00:00:00 UTC 开始的秒数(time_t类型) -
std::localtime()把它转成本地时区的tm结构,tm.tm_year是从 1900 年起算,tm.tm_mon从 0 开始(0 表示 1 月) - 若需线程安全,改用
localtime_r()(POSIX)或localtime_s()(Windows)
用 sprintf 或 std::strftime 格式化输出日期字符串
std::strftime() 是专为 tm 结构设计的格式化函数,比手拼字符串更可靠、支持时区符号(如 %Z)、自动补零等。别用 sprintf 直接格式化 tm 成员——容易漏掉 +1900、+1 等偏移,也难处理宽字符或 locale。
典型格式符:%Y(4 位年),%m(01–12),%d(01–31),%H:%M:%S(时分秒)。注意 %y 是两位年(如 24),%Y 是四位(2024)。
立即学习“C++免费学习笔记(深入)”;
- 缓冲区大小要留足,例如
char buf[64]足够放完整日期时间加时区 -
strftime()返回实际写入字符数(不含结尾\0),返回 0 表示失败(比如缓冲区太小或格式非法) - 格式字符串里普通字符(如空格、短横)会原样保留,
"%Y-%m-%d %H:%M:%S"输出类似"2024-05-21 14:36:02"
C++20 + 更现代但要注意兼容性
如果你用的是 C++20 编译器(如 GCC 13+、Clang 15+、MSVC 19.33+),可以直接用 std::chrono::system_clock::now() 配合 std::format(),无需手动转 tm:
auto now = std::chrono::system_clock::now();
auto time_t = std::chrono::system_clock::to_time_t(now);
std::cout << std::format("{:%Y-%m-%d %H:%M:%S}", std::chrono::system_clock::from_time_t(time_t)) << '\n';
但注意:std::format 在某些标准库实现中仍不完全支持日期格式(如 libstdc++ 早期版本),编译可能报错 no matching function for call to 'format'。此时退回 strftime 最稳妥。
-
std::chrono::system_clock的精度通常是纳秒或微秒,但to_time_t()会截断到秒 -
std::format的日期格式语法和strftime不同(如{:%Y}对应%Y),不能混用 - 若只需毫秒级时间戳整数,直接用
auto ms = std::chrono::duration_cast<:chrono::milliseconds>(now.time_since_epoch()).count();
跨平台获取 UTC 时间避免本地时区干扰
很多日志、协议交互需要 UTC 时间而非本地时间。用 std::gmtime() 替代 std::localtime() 即可,其余流程一致。但注意:gmtime() 同样是非线程安全的静态缓冲区版本。
容易被忽略的一点:Windows 下 gmtime() 和 localtime() 默认行为与 POSIX 一致,但若程序设置了 _tzset() 或环境变量 TZ,可能影响 localtime(),而 gmtime() 不受影响。
- UTC 时间不随系统时区设置变化,适合服务器统一时间基准
- 用
std::strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%SZ", gmtime(&t))可生成 ISO 8601 UTC 格式(末尾 Z 表示 zero offset) - 若需带毫秒的 UTC 字符串,仍得先取
system_clock::now(),再减去time_t对应的秒数,单独提取毫秒部分










