这段实现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++;
}