最简单获取秒级Unix时间戳的方法是std::time(nullptr),返回自1970-01-01 UTC起的秒数,类型为std::time_t,需#include <ctime>,线程安全且时区无关;注意它仅精确到秒,非毫秒/微秒,32位系统存在2038年溢出风险。

用 std::time 获取秒级时间戳最简单
直接调用 std::time(nullptr) 就能拿到 Unix 时间戳(自 1970-01-01 00:00:00 UTC 起的秒数),返回类型是 std::time_t,通常等价于 long 或 long long,可直接用于日志、文件名、缓存键等场景。
常见错误是误以为它返回毫秒或微秒——它只精确到秒,且不保证跨平台行为完全一致(比如某些嵌入式系统上 std::time_t 可能是 32 位,2038 年后溢出)。
- 不需要额外头文件,
#include <ctime>即可 - 线程安全:
std::time是无状态函数,可多线程并发调用 - 时区无关:返回的是 UTC 时间戳,不随本地时区变化
- 示例:
auto ts = std::time(nullptr); // 返回类似 1717023456
为什么不用 std::chrono::system_clock::now()?
它更现代、类型安全,但默认返回的是纳秒级 std::chrono::time_point,要转成秒级时间戳需手动截断和转换,容易出错。
典型误操作是直接用 .time_since_epoch().count()——这返回的是纳秒数(极大整数),不是秒数;漏掉除法或单位转换会导致时间错乱 10⁹ 倍。
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 正确做法:
auto now = std::chrono::system_clock::now();<br>auto ts = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count();
- 注意:
std::chrono::seconds::count()返回rep类型(通常是long long),别和int混用 - 性能差异几乎为零,但代码更长,对纯秒级需求属于过度设计
Windows 下 GetTickCount64 不是时间戳
有人搜“C++ 获取当前时间”会撞见 GetTickCount64,但它返回的是系统启动后经过的毫秒数,不是 Unix 时间戳,不能直接用于跨进程/跨机器的时间比较。
它从开机开始计数,每次重启归零,且不反映真实 UTC 时间。拿它当时间戳用,会导致日志时间错乱、缓存失效失败、API 签名验证失败等问题。
- 仅适合测量持续时间(如性能打点),绝不用于生成时间戳
- 即使换算成秒,起点也不是 1970,无法和标准时间对齐
- 跨平台代码中应彻底避免使用
需要高精度或跨平台一致性时怎么选?
如果项目明确要求 C++11 以上、且未来可能扩展到毫秒级,std::chrono 是唯一可靠路径;但如果只要秒级、兼容旧代码、或目标环境是嵌入式/老编译器,std::time 更稳。
一个常被忽略的点:某些裁剪版 libc(如 musl 在某些 Alpine 镜像中)对 std::time_t 的定义可能与 glibc 不同,但秒级值本身仍是标准 Unix 时间戳,只要不直接 reinterpret_cast 成指针或做位运算就没事。
- 别自己手写 epoch 计算(比如用
localtime+ 手动加减),误差不可控 - 不要依赖
time(NULL)的返回值是否为负——POSIX 允许其在 1970 年前返回负值,但实际极少遇到 - 若需格式化输出,再用
std::gmtime或std::localtime,和获取时间戳是两件事

















