如何解析boost::interprocess::winapi::get_last_bootup_time()的输出字符串并转换为Unix时间以判断系统启动时长?
Hey there! Let's break down your question step by step, from what that weird hex string means to how you can convert it into a usable Unix timestamp for your check.
解析输出字符串 AA000000_0E030000
First off, that string is a hexadecimal representation of Windows' FILETIME structure—this is what boost::interprocess::winapi::get_last_bootup_time() pulls from the underlying Windows API.
The FILETIME is a 64-bit value split into two 32-bit chunks: the low-order DWORD and high-order DWORD. The underscore in your output separates these two parts:
AA000000is the low-order DWORD (stored in little-endian, so reverse the byte order to get0x000000AA)0E030000is the high-order DWORD (also little-endian, reversed to0x0000030E)
Combined, this gives a full 64-bit FILETIME value: 0x0000030E000000AA. This number counts the number of 100-nanosecond intervals since January 1, 1601 (UTC)—the baseline Windows uses for time calculations.
转换为标准Unix时间戳
Unix timestamps count seconds since January 1, 1970 (UTC), so we need to bridge the gap between these two time baselines. Here's a code implementation to do this:
#include <boost/interprocess/detail/win32_api.hpp> #include <sstream> #include <iomanip> #include <cstdint> #include <ctime> uint64_t filetimeToUnixTimestamp(const std::string& bootTimeStr) { // Split the string into low and high hex parts size_t underscorePos = bootTimeStr.find('_'); std::string lowHex = bootTimeStr.substr(0, underscorePos); std::string highHex = bootTimeStr.substr(underscorePos + 1); // Convert hex strings to DWORDs, correcting for little-endian byte order uint32_t lowDword; std::istringstream(lowHex) >> std::hex >> lowDword; lowDword = _byteswap_ulong(lowDword); uint32_t highDword; std::istringstream(highHex) >> std::hex >> highDword; highDword = _byteswap_ulong(highDword); // Combine into a 64-bit FILETIME value uint64_t filetime = (static_cast<uint64_t>(highDword) << 32) | lowDword; // Convert to Unix timestamp: subtract the 1601-1970 interval, then convert to seconds const uint64_t epochOffset = 116444736000000000ULL; // Fixed 100ns count between 1601 and 1970 uint64_t unixTime = (filetime - epochOffset) / 10000000ULL; return unixTime; }
判断系统是否在最近5分钟内启动
Once you have the boot time as a Unix timestamp, comparing it to the current time is straightforward. Here's a helper function to do the check:
bool isSystemBootedInLastFiveMinutes() { std::string bootTimeStr; if (!boost::interprocess::winapi::get_last_bootup_time(bootTimeStr)) { // Handle error if we can't retrieve the boot time return false; } uint64_t bootUnixTime = filetimeToUnixTimestamp(bootTimeStr); uint64_t currentUnixTime = std::time(nullptr); const uint64_t fiveMinutesInSeconds = 5 * 60; return (currentUnixTime - bootUnixTime) < fiveMinutesInSeconds; }
Call isSystemBootedInLastFiveMinutes() and it will return true if the system started up within the last 5 minutes, otherwise false.
内容的提问来源于stack exchange,提问作者Mona

