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

将tm_hour设为0后dateplusdays函数加天操作异常的原因排查

日期加天数函数的夏令时异常原因分析

以下是实现yyyymmdd格式日期加天数功能的dateplusdays函数:

int dateplusdays(int datein, int days) {
    int year, month, day;
    int dateout;
    struct tm date;
    time_t secs;

    year = (int)floor(datein / 10000.0);
    month = (int)floor(datein / 100.0) - year * 100;
    day = datein - month * 100 - year * 10000;

    date.tm_sec = 0;
    date.tm_min = 0;
    date.tm_hour = 12;
    date.tm_year = year - 1900;
    date.tm_mon = month - 1;
    date.tm_mday = day;
    date.tm_isdst = -1;
    
    secs = mktime(&date) + days * 86400;
    date = *localtime(&secs);

    dateout = (date.tm_year + 1900) * 10000 + (date.tm_mon + 1) * 100 + date.tm_mday;
    
    return dateout;
}

使用以下测试代码对1900-2100年的日期压测,未发现错误:

for (i = 19000101; i < 21001231; i++) {
    int a = dateplusdays(i, 0); // 将i转换为有效日期
    if (i == a) { // 验证是有效日期
        int b = dateplusdays(a, 1);
        int c = dateplusdays(b, 1);
        if (b == c)
            printf("i:%d a:%d b:%d c:%d\n", i, a, b, c);
    }
}

但将date.tm_hour从12改为0后,1900-2100区间出现184个特定日期错误,例如2022年10月30日加1天仍为当天,错误集中在9-11月:

geohei@vm92:~/Devel$ ./dateplusdays | cut -c7-8 | sort | uniq -c
     47 09
    131 10
      6 11

异常原因

这个问题是**夏令时(DST,Daylight Saving Time)**切换导致的:

  • 当tm_hour设为0时,对应日期的午夜0点。在夏令时结束的日期(比如北半球部分地区的10月最后一个周日),时钟会从凌晨2:00回拨到1:00,这一天实际有25个小时。
  • 此时给该日期的0点加上86400秒(24小时),实际只走到了当天的23:00(因为有1小时的时间重复),所以localtime解析后得到的仍然是当天的日期,出现加1天却日期不变的错误。
  • 而将tm_hour设为12点时,这个时间点避开了夏令时切换的凌晨窗口,加24小时后必然进入下一天,不会触发这个问题。

错误集中在9-11月,正是北半球夏令时结束的时间段,回拨调整导致当天时长超过24小时,从而引发计算异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 03:50:17