如何在C++中实现Excel NOW格式日期时间的转换?
实现Excel日期时间到标准格式的C++转换
首先明确Excel的日期时间存储规则:
- 数值的整数部分是从1900年1月1日开始累计的天数(注意Excel有个历史bug:错误地将1900年视为闰年,所以如果天数≤60,需要额外调整,你的示例44916远大于60,暂时不用考虑这个情况)。
- 数值的小数部分是一天的比例,比如0.3就代表0.3×24=7.2小时,0.2小时=12分钟,对应07:12:00。
接下来是具体的C++实现思路和代码:
步骤拆解
- 拆分输入的浮点数为整数天数和小数时间部分;
- 计算基准日期(1900-01-01)加上天数后的实际日期;
- 将小数部分转换为时分秒;
- 拼接成所需的日期时间字符串。
代码实现
#include <iostream> #include <iomanip> #include <chrono> #include <cmath> #include <sstream> // 转换Excel日期值为YYYY-MM-DD HH:MM:SS格式字符串 std::string excelDateTimeToStr(double excelValue) { // 拆分整数天数和小数部分 long long days = static_cast<long long>(std::floor(excelValue)); double fraction = excelValue - days; // 处理Excel 1900闰年bug:如果天数<=60,实际要减1天 if (days <= 60) { days--; } // 基准日期:1900-01-01,基于C++20 chrono库计算目标日期 const std::chrono::sys_days excelBase = std::chrono::year{1900}/1/1; std::chrono::sys_days targetDate = excelBase + std::chrono::days(days); // 转换为tm结构用于格式化 std::time_t tt = std::chrono::system_clock::to_time_t(targetDate); std::tm tm = *std::localtime(&tt); // 把小数部分转成时分秒 long long totalSeconds = static_cast<long long>(std::round(fraction * 86400)); // 一天共86400秒 int hours = totalSeconds / 3600; int remaining = totalSeconds % 3600; int minutes = remaining / 60; int seconds = remaining % 60; // 格式化输出字符串 std::ostringstream oss; oss << std::put_time(&tm, "%Y-%m-%d") << " " << std::setw(2) << std::setfill('0') << hours << ":" << std::setw(2) << std::setfill('0') << minutes << ":" << std::setw(2) << std::setfill('0') << seconds; return oss.str(); } int main() { double excelVal = 44916.3; std::string result = excelDateTimeToStr(excelVal); std::cout << result << std::endl; // 输出:2022-12-21 07:12:00 return 0; }
注意事项
- 代码依赖C20的
<chrono>库处理日期运算,兼容性更优;如果你的编译器不支持C20,可以改用手动计算日期的方式(基于tm结构逐步加减天数,需额外处理闰年、各月天数等细节)。 - 若数据可能包含1900年3月1日之前的日期,必须保留
if (days <= 60) days--;这一行,否则转换结果会出错(比如Excel的60对应虚构的1900-02-29,实际需转换为1900-03-01)。 - 小数部分用
std::round处理是为了避免浮点精度误差,保证秒数计算准确。
内容的提问来源于stack exchange,提问作者Daddedebad
相关产品推荐
相关产品推荐

