C++ 怎么获取当前时间 C++ ctime库与格式化输出代码【日期】

2次阅读

最直接方式是用 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 格式。

C++ 怎么获取当前时间 C++ ctime库与格式化输出代码【日期】

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

sprintfstd::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 表示失败(比如缓冲区太小或格式非法)
  • 格式字符串里普通字符(如空格、短横)会原样保留,"%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 对应的秒数,单独提取毫秒部分

text=ZqhQzanResources