Linux下获取系统启动时间最轻量可靠的方式是调用sysinfo()系统调用获取uptime秒数,再用time(nullptr)减去该值反推启动时刻;需包含和,注意32位系统约497天后uptime会溢出。

Linux 下用 sysinfo() 获取系统启动时间(秒级)
最轻量、最可靠的方式是调用 sysinfo() 系统调用,它直接返回自系统启动以来的 uptime 秒数,再减去当前时间戳就能反推启动时刻。
注意:sysinfo() 返回的是 uptime(单位秒),不是绝对时间;你需要用 time(nullptr) 获取当前秒级时间戳,相减后转成 struct tm 才能读得懂。
-
sysinfo()不依赖 /proc 文件系统,即使在容器或 chroot 中也能工作 - 返回值是
long类型的 uptime,32 位系统下约 497 天后会溢出(但现代服务器基本都跑 64 位) - 需要包含头文件
<sys></sys>和<time.h></time.h>
struct sysinfo info;
if (sysinfo(&info) == 0) {
time_t boot_time = time(nullptr) - info.uptime;
struct tm *tm = localtime(&boot_time);
printf("Boot time: %d-%02d-%02d %02d:%02d:%02d\n",
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
}/proc/uptime 是更通用的替代方案(Linux only)
如果不想调用系统 API,或者需要更高精度(小数秒),/proc/uptime 是首选。它第一字段就是 uptime(浮点数),第二字段是 idle 时间,只取第一个即可。
这个方式在绝大多数 Linux 发行版和容器环境中都可用,但严格来说不属于 POSIX,不能跨平台。
立即学习“C++免费学习笔记(深入)”;
- 读取时需用
fscanf()或std::stod()解析浮点数,别用整数读取否则丢精度 - 路径是硬编码的
/proc/uptime,不能省略斜杠,也不能写成proc/uptime - 如果程序以非 root 用户运行,该文件始终可读——无需提权
Windows 上用 GetTickCount64() 反推启动时间
Windows 没有直接的“系统启动时间” API,但 GetTickCount64() 返回的是开机后毫秒数,用 GetSystemTimeAsFileTime() 获取当前时间,两者相减就能算出启动时刻。
关键点在于:Windows 的 FILETIME 是 100 纳秒为单位的 64 位计数,要先转成毫秒再减,否则溢出或截断。
- 必须用
GetTickCount64(),GetTickCount()是 32 位,49.7 天就回绕 - FILETIME 转毫秒:先转成 64 位整数,除以 10000(因为 1 ms = 10000 × 100 ns)
- 结果是本地时间,若需 UTC,用
FileTimeToSystemTime()配合SYSTEMTIME
跨平台封装要注意的三个坑
真正在项目里做跨平台封装时,最容易栽在时区、精度和错误处理上。
- Linux 的
localtime()和 Windows 的FileTimeToSystemTime()默认都按本地时区转换,如果服务部署在 UTC 服务器但日志要 GMT,得统一用gmtime()或SystemTimeToTzSpecificLocalTime() -
/proc/uptime提供小数秒,sysinfo()只给整秒——如果你依赖毫秒级精度做监控对齐,别混用 - Windows 下
GetTickCount64()在休眠期间不递增,而 Linux 的 uptime 会计入休眠时间,行为本质不同,不能假设二者数值可比
系统启动时间不是个“查一下就完”的值,它背后绑定着 uptime 语义、时钟源、电源状态,用之前先想清楚你要对齐的是 wall-clock 还是 active-running 时间。


















