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

C++如何获取两个int类型日期闭区间内的所有日期?

实现方案

你现有思路完全可行,核心是利用std::mktime会自动归一化越界日期字段的特性:每次给tm_mday加1后调用std::mktime,函数会自动处理跨月、跨年、闰年、夏令时的偏移,不需要手动写复杂的日期进位逻辑。

基于std::tm的可运行实现

首先需要注意你现有make_tm函数的隐患:栈上创建的std::tm如果不做零初始化,tm_hour/tm_min/tm_sec/tm_isdst等字段会是随机垃圾值,可能导致std::mktime计算结果异常,修正后的工具函数和遍历逻辑如下:

#include <vector>
#include <ctime>
#include <cstdint>

// 修正后的int转std::tm函数
std::tm make_tm(int32_t s) {
    int32_t s_year = s / 10000;
    int32_t s_mon = s % 10000 / 100;
    int32_t s_day = s % 100;
    std::tm st{}; // 零初始化所有字段,消除垃圾值影响
    st.tm_year = s_year - 1900;
    st.tm_mon = s_mon - 1;
    st.tm_mday = s_day;
    st.tm_isdst = -1; // 交由系统自动判断夏令时,避免手动设置错误
    std::mktime(&st);
    return st; 
}

// 辅助函数:std::tm转回YYYYMMDD格式的int32_t
int32_t tm_to_int(const std::tm& t) {
    return (t.tm_year + 1900) * 10000 + (t.tm_mon + 1) * 100 + t.tm_mday;
}

// 核心:生成闭区间日期序列
std::vector<int32_t> get_date_range(int32_t start_date, int32_t end_date) {
    std::vector<int32_t> res;
    // 非法输入直接返回空数组
    if (start_date > end_date) {
        return res;
    }
    std::tm current = make_tm(start_date);
    res.push_back(start_date);
    while (true) {
        current.tm_mday += 1;
        std::mktime(&current); // 自动修正日期越界
        int32_t cur_val = tm_to_int(current);
        if (cur_val > end_date) {
            break;
        }
        res.push_back(cur_val);
    }
    return res;
}

调用get_date_range(20220620, 20220622)即可得到你预期的std::vector<int32_t>{20220620, 20220621, 20220622}结果。

更轻量的无依赖实现

如果你的业务场景不需要处理复杂的时区、夏令时规则,只是处理常规公历日期,可以直接手动实现日期进位逻辑,完全不依赖C标准库时间函数,性能更高,也不会因为服务器时区配置异常出现计算偏差:

#include <vector>
#include <cstdint>

// 闰年判断
bool is_leap_year(int year) {
    return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}

// 获取指定年月的总天数
int get_month_max_day(int year, int month) {
    static const int month_days[] = {31,28,31,30,31,30,31,31,30,31,30,31};
    if (month == 2 && is_leap_year(year)) {
        return 29;
    }
    return month_days[month - 1];
}

std::vector<int32_t> get_date_range_fast(int32_t start_date, int32_t end_date) {
    std::vector<int32_t> res;
    if (start_date > end_date) {
        return res;
    }
    int year = start_date / 10000;
    int month = (start_date % 10000) / 100;
    int day = start_date % 100;

    while (true) {
        int32_t cur_date = year * 10000 + month * 100 + day;
        if (cur_date > end_date) {
            break;
        }
        res.push_back(cur_date);
        // 日期进位
        day += 1;
        int max_day = get_month_max_day(year, month);
        if (day > max_day) {
            day = 1;
            month += 1;
            if (month > 12) {
                month = 1;
                year += 1;
            }
        }
    }
    return res;
}

方案选择建议

  • 若需要兼容历史日期、严格匹配本地时区时间规则,选择std::tm实现,标准库已经覆盖了所有时间计算的边界场景
  • 若只是处理常规业务日期、追求性能和稳定性,选手动进位的轻量实现,无隐式环境依赖

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 19:24:28