月度重复交易日期计算异常:二月被跳过问题排查
问题排查与修复方案
核心问题1:月末日期计算错误
adjustToLastDayOfMonth函数中错误地将日期设置为当月最后一天的前一天(lastDay -1),这不仅导致月末日期偏移,还会在处理二月时,因日期提前触发循环条件跳过二月。
修复代码:
const adjustToLastDayOfMonth = (date: Date) => { const lastDay = getLastDayOfMonth(date.getFullYear(), date.getMonth()); const adjustedDate = new Date(date); // 去掉-1,直接取当月最后一天或原日期的较小值 adjustedDate.setDate(Math.min(date.getDate(), lastDay)); return adjustedDate; };
核心问题2:月度递增时的日期溢出处理不当
月度重复逻辑中,先递增月份再设置日期的方式,会导致当原日期大于目标月份最大天数时(比如31号),Date对象自动将日期溢出到下一个月,直接跳过二月。例如1月31号执行setMonth(1)(二月)后,再setDate(31)会自动变成3月3日,后续调整操作会转为3月31日,完全跳过二月。
修复后的月度循环逻辑:
case 'monthly': const nextMonthNum = currentDate.getMonth() + 1; const targetYear = currentDate.getFullYear() + (nextMonthNum > 11 ? 1 : 0); const targetMonth = nextMonthNum % 12; // 先尝试设置目标日期为起始日期的天数 const tempDate = new Date(targetYear, targetMonth, startDate.getDate()); // 如果设置后的月份与目标月份不一致,说明日期溢出,直接设为当月最后一天 if (tempDate.getMonth() !== targetMonth) { currentDate = new Date(targetYear, targetMonth + 1, 0); } else { currentDate = adjustToLastDayOfMonth(tempDate); } break;
额外优化(可选)
bi-monthly和yearly分支也存在相同的日期溢出问题,可按相同逻辑修复:
修复bi-monthly:
case 'bi-monthly': const biNextMonthNum = currentDate.getMonth() + 2; const biTargetYear = currentDate.getFullYear() + (biNextMonthNum > 11 ? Math.floor(biNextMonthNum / 12) : 0); const biTargetMonth = biNextMonthNum % 12; const biTempDate = new Date(biTargetYear, biTargetMonth, startDate.getDate()); if (biTempDate.getMonth() !== biTargetMonth) { currentDate = new Date(biTargetYear, biTargetMonth + 1, 0); } else { currentDate = adjustToLastDayOfMonth(biTempDate); } break;
修复yearly:
case 'yearly': const nextYear = currentDate.getFullYear() + 1; const yearlyTempDate = new Date(nextYear, currentDate.getMonth(), startDate.getDate()); // 处理闰年转非闰年的二月29号情况 if (yearlyTempDate.getMonth() !== currentDate.getMonth()) { currentDate = new Date(nextYear, currentDate.getMonth() + 1, 0); } else { currentDate = adjustToLastDayOfMonth(yearlyTempDate); } break;
内容的提问来源于stack exchange,提问作者Cleardragonf
相关产品推荐
相关产品推荐

