看看这段代码有啥问题

这段实现mktime()的代码哪里有问题啊,输出一直和真实值有几万差别

#include 
#include 
using namespace std;
// 表格:存储全部闰秒时间
const time_t leap_seconds_table[] = {
    78796800, 94694400, 126230400, 157766400, 189302400, 220924800,
    252460800, 283996800, 315532800, 362793600, 394329600, 425865600,
    489024000, 567993600, 631152000, 662688000, 709948800, 741484800,
    773020800, 820454400, 867715200, 915148800, 1136073600, 1230768000,
    1341100800, 1435708800, 1483228800, 1525708800, 1577664000, 1629936000,
    1672473600, 1724835200, 1777296000, 1893024000, 1935484800, 1988112000,
    1996489600 // 最后一个闰秒(2016年12月31日23时59分60秒)
};
const int leap_seconds_table_size = sizeof(leap_seconds_table) / sizeof(time_t);
// 判断指定年份是否为闰年
bool is_leap_year(int year) {
    return ((year % 4== 0 && year %100!= 0) || year %400== 0);
}
// 计算指定年份的秒数
int get_year_seconds(int year) {
    return (is_leap_year(year) ? 366 : 365) * 86400;
}
// 计算指定年份月份的秒数
int get_month_seconds(int year, int month) {
    static int month_days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    int seconds = month_days[month] * 86400;
    if (is_leap_year(year) && month == 1) { // 闰年的2月有29天
        seconds += 86400;
    }
    return seconds;
}
// 计算指定日期时间的秒数
time_t my_mktime(struct tm* timeinfo) {
    time_t epoch_time;
    epoch_time = 0;
    for (int year = 1970; year < timeinfo->tm_year + 1900; year++) {
        epoch_time += get_year_seconds(year);
    }
    for (int month = 0; month < timeinfo->tm_mon; month++) {
        epoch_time += get_month_seconds(timeinfo->tm_year + 1900, month);
    }
    epoch_time += (timeinfo->tm_mday - 1) * 86400;
    epoch_time += timeinfo->tm_hour * 3600;
    epoch_time += timeinfo->tm_min * 60;
    epoch_time += timeinfo->tm_sec;
    // 处理时区偏移量
    epoch_time -= timeinfo->tm_gmtoff;
    // 处理闰秒
    for (int i = 0; i < leap_seconds_table_size; i++) {
        if (epoch_time < leap_seconds_table[i]) {
            break;
        }
        epoch_time++;
    }
    return epoch_time;
}
int main() {
    struct tm timeinfo = { 0 };
    timeinfo.tm_year = 2022 - 1900;
    timeinfo.tm_mon = 11;
    timeinfo.tm_mday = 31;
    timeinfo.tm_hour = 23;
    timeinfo.tm_min = 59;
    timeinfo.tm_sec = 59;
    timeinfo.tm_isdst = -1; // 标志位设为-1,让系统自动判断是否处于夏令时
    timeinfo.tm_gmtoff = 8 * 3600; // 时区偏移量,北京时间为东8区
    time_t epoch_time = my_mktime(&timeinfo);
    cout << "Epoch time: " << epoch_time << endl<<mktime(&timeinfo);
    return 0;
}

“Devil组”引证GPT后的撰写:
这段代码有两个问题:

1.在计算月份秒数时,数组下标越界,应该是<=

for (int month = 0; month < timeinfo->tm_mon; month++) {
    epoch_time += get_month_seconds(timeinfo->tm_year + 1900, month);
}


timeinfo->tm_mon表示的是月份,范围是0~11,所以在计算月份秒数时,数组下标需要加1。修改为:

for (int month = 0; month <= timeinfo->tm_mon; month++) {
    epoch_time += get_month_seconds(timeinfo->tm_year + 1900, month);
}


2.在处理闰秒时,应该先将时间减去闰秒,再进行比较。当前代码是在时间大于等于闰秒时,才将时间加1,这会导致输出的时间比实际时间大1秒。修改为:

for (int i = 0; i < leap_seconds_table_size; i++) {
    epoch_time -= leap_seconds_table[i];
    if (epoch_time < leap_seconds_table[i]) {
        epoch_time += leap_seconds_table[i];
        break;
    }
    epoch_time++;
}