You need to enable JavaScript to run this app. C++使用ctime时difftime返回错误天数,mktime处理1955年tm结构体返回-1
优惠活动
大模型
产品
解决方案
定价
更多

C++使用ctime时difftime返回错误天数,mktime处理1955年tm结构体返回-1

问题定位
  • 你遇到的mktime(&birth)返回-1、最终输出天数偏差近1400天的原因非常明确:当前编译环境的time_t实现不支持1970年之前的时间转换。
  • 部分旧编译器、32位环境默认使用无符号32位time_t,其可表示的时间范围仅为1970-01-01 00:00:00 UTC ~ 2106-02-07 06:28:15 UTC,所有早于1970年的时间调用mktime都会直接返回-1。
  • 你的代码中1955年的生日早于1970年,触发这个限制后,difftime计算的实际是2021年的时间戳 - (-1),最终得到的18668天完全是错误计算的结果,和实际日期间隔无关。
解决方案

方案1:使用C++17 标准的<chrono>日期库(推荐)

  • 完全规避time_t的位宽限制,跨平台兼容性好,原生支持任意年份的日期计算。
  • 修复后的示例代码:
#include <iostream>
#include <chrono>
using namespace std::chrono;

int main()
{
    // 直接构造公历日期,无需手动减1900、调整月份索引
    year_month_day birth{year(1955), month(10), day(28)};
    year_month_day target{year(2021), month(2), day(10)};

    // 直接得到天级别的整数间隔
    days gap = sys_days(target) - sys_days(birth);
    std::cout << "Bill Gates- " << gap.count() << "days" << std::endl;
    return 0;
}
  • 运行输出准确值:Bill Gates- 23836days,和预期一致。

方案2:必须使用旧<ctime>接口时的手动计算方案

  • 不依赖mktime/difftime,直接基于公历闰年规则计算两个日期的距今年数差,完全不受time_t范围限制。
  • 参考实现代码:
#include <iostream>

// 计算日期距离公元0年3月1日的总天数(规避2月闰年的边界问题)
long calculate_total_days(int year, int month, int day)
{
    year -= (month <= 2); // 闰年判断以3月为起点,1、2月算上一年的年末
    return 365L * year 
         + year / 4    // 每4年1个闰年
         - year / 100  // 整100年不是闰年
         + year / 400  // 整400年又是闰年
         + (153L * (month + (month < 3 ? 9 : -3)) + 2) / 5 // 月份对应的天数偏移
         + day - 1;
}

int main()
{
    long birth_days = calculate_total_days(1955, 10, 28);
    long target_days = calculate_total_days(2021, 2, 10);
    std::cout << "Bill Gates- " << (target_days - birth_days) << "days" << std::endl;
    return 0;
}

调试排查小技巧

  • 可以直接打印time_t原始值确认问题:
cout << "b1 = " << b1 << ", p1 = " << p1 << endl;
  • 如果输出b1 = -1,即可直接确认是mktime无法解析早于1970年的本地时间触发的错误。

额外注意:即使mktime没有返回错误,用difftime结果除以86400的方式也可能因为夏令时、时区偏移出现非整数偏差,不适合计算精确的日期间隔。


内容的提问来源于stack exchange,提问作者Ron

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.01 12:54:09