C++:如何将1601年1月1日起的100纳秒时间戳转为日期时间
使用C++ chrono库转换1601起始的100纳秒时间戳到DD-MM-YYYY HH:MM:SS格式
一、直接用现代C++ chrono库实现
这种时间戳是自1601年1月1日起的100纳秒间隔数(与Windows FILETIME格式一致),chrono库没有直接提供该起始点,我们可以通过计算它与Unix时间戳起点(1970-01-01 00:00:00)的差值来转换:
核心逻辑
- 定义以100纳秒为单位的
duration类型,匹配时间戳精度 - 计算1601-01-01到1970-01-01的时间差:共
11644473600秒,对应116444736000000000个100纳秒间隔 - 输入时间戳减去该差值,得到Unix时间轴上的时间点
- 用C++20的
std::format或传统std::put_time格式化输出目标格式
代码示例
#include <chrono> #include <format> #include <iostream> #include <cstdint> int main() { // 示例100纳秒时间戳 const uint64_t timestamp_100ns = 133172256000000000ULL; // 定义100纳秒单位的duration using hundred_ns = std::chrono::duration<uint64_t, std::ratio<1, 10000000>>; const auto tp_1601 = hundred_ns{timestamp_100ns}; // 1601到Unix纪元的时间差(转换为100纳秒单位) constexpr auto unix_epoch_diff = std::chrono::seconds{11644473600}; const auto tp_unix = std::chrono::time_point<std::chrono::system_clock>{ std::chrono::duration_cast<std::chrono::system_clock::duration>(tp_1601 - hundred_ns{unix_epoch_diff}) }; // 格式化输出DD-MM-YYYY HH:MM:SS(C++20及以上) std::cout << std::format("{:%d-%m-%Y %H:%M:%S}", tp_unix) << '\n'; return 0; }
二、复用Excel公式逻辑实现
你提到的Excel公式核心是将100纳秒时间戳转换为Excel日期数值(以1899-12-31为起点的天数),这个逻辑可以直接在C++中复用:
Excel公式解析
8.64*10^11是一天包含的100纳秒数(计算:24*60*60*10^7 = 864000000000)109205是1601-01-01到Excel起始点(1899-12-31)的天数
C++实现步骤
- 将输入时间戳转换为天数,加上109205得到Excel日期数值
- 拆分整数部分(天数)和小数部分(时分秒比例)
- 组合日期与时间部分后格式化输出
代码示例
#include <chrono> #include <format> #include <iostream> #include <cstdint> int main() { const uint64_t timestamp_100ns = 133172256000000000ULL; const uint64_t ns_per_day = 864000000000ULL; // 一天的100纳秒数 // 计算Excel日期数值 const double excel_date = static_cast<double>(timestamp_100ns) / ns_per_day + 109205.0; // 拆分天数和时分秒比例 const int days = static_cast<int>(excel_date); const double fraction = excel_date - days; // Excel起始点转换为chrono时间点 const auto excel_epoch = std::chrono::sys_days{std::chrono::year{1899}/12/31}; const auto date_part = excel_epoch + std::chrono::days{days}; const auto time_part = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::duration<double>{fraction * 86400}); // 组合并格式化输出 const auto tp = date_part + time_part; std::cout << std::format("{:%d-%m-%Y %H:%M:%S}", tp) << '\n'; return 0; }
注意事项
- 两种实现均需要C++20及以上版本以支持
std::format和std::chrono::sys_days;若使用旧版本,可替换为std::put_time完成格式化 - 时间戳数值需确保在
uint64_t范围内(最大值对应约584942417355年)
内容的提问来源于stack exchange,提问作者Arun
相关产品推荐
相关产品推荐

