You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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++实现思路和代码:

步骤拆解

  1. 拆分输入的浮点数为整数天数和小数时间部分;
  2. 计算基准日期(1900-01-01)加上天数后的实际日期;
  3. 将小数部分转换为时分秒;
  4. 拼接成所需的日期时间字符串。

代码实现

#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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 23:30:22