JavaScript计算rentInPeriod时乘法结果与预期不符问题求助
问题根因
- 时间差统计逻辑错误:你实现的
Days360方法未做标准月末日期对齐处理,导致完整12个月的周期(例如2021.12.1~2022.11.30)被统计为359天而非360天,计算得到的monthsInPeriod实际值为359/360*12≈11.9667,只是最终返回时四舍五入显示为12。 - 四舍五入时机错误:当前返回的
rentInPeriod是用未四舍五入的原始monthlyRent、原始monthsInPeriod相乘后四舍五入得到的,而预期是用已经四舍五入后显示的monthlyRent、monthsInPeriod相乘得到结果,两种计算方式自然存在偏差。
修复方案
可根据业务需求二选一:
方案1:与参考表格总金额$18,098,798完全对齐
你所有生效的调整周期都是完整12个月,无需按天折算,直接取对应周期的年租金即可:
function Compute(scheduleData: any): any { let startDate = typeof scheduleData.startDate === 'string' ? new Date(scheduleData.startDate) : scheduleData.startDate; const endDate = typeof scheduleData.endDate === 'string' ? new Date(scheduleData.endDate) : scheduleData.endDate; if (!startDate || startDate.toString() === 'Invalid Date') { startDate = effectiveDate; } // 周期在生效日期之前的租金为0 if(endDate <= effectiveDate) { return { description: scheduleData.description, monthlyRent: Math.round(scheduleData.annualRent / 12), monthsInPeriod: 0, rentInPeriod: 0, } } const monthlyRent = scheduleData.annualRent / 12; return { description: scheduleData.description, monthlyRent: Math.round(monthlyRent), monthsInPeriod: 12, rentInPeriod: Math.round(scheduleData.annualRent), }; }
方案2:保留按天折算逻辑,修正计算规则
先补全Days360的月末对齐逻辑,同时调整四舍五入时机,用最终显示的数值计算周期租金:
// 符合US 30/360标准的Days360实现 function Days360(startDate: Date, endDate: Date, decimalPlace: number = 2): number | undefined { if (!startDate || !endDate) return undefined; let startDay = startDate.getDate(); const startMonth = startDate.getMonth(); const startYear = startDate.getFullYear(); let endDay = endDate.getDate(); const endMonth = endDate.getMonth(); const endYear = endDate.getFullYear(); const isLastDayOfMonth = (d: Date) => new Date(d.getFullYear(), d.getMonth()+1, 0).getDate() === d.getDate(); // 起始日为当月最后一天则调整为30号 if (isLastDayOfMonth(startDate)) startDay = 30; // 结束日为当月最后一天且起始日>=30则调整为30号 if (isLastDayOfMonth(endDate) && startDay >= 30) endDay = 30; startDay = startDay > 30 ? 30 : startDay; endDay = endDay > 30 ? 30 : endDay; return parseFloat(((endYear - startYear)*360 + (endMonth - startMonth)*30 + (endDay - startDay)).toFixed(decimalPlace)); } // 调整Compute方法的四舍五入时机 function Compute(scheduleData: any): any { let startDate = typeof scheduleData.startDate === 'string' ? new Date(scheduleData.startDate) : scheduleData.startDate; const endDate = typeof scheduleData.endDate === 'string' ? new Date(scheduleData.endDate) : scheduleData.endDate; if (!startDate || startDate.toString() === 'Invalid Date') { startDate = effectiveDate; } const rawMonthlyRent = scheduleData.annualRent / 12; let range360: any = startDate <= effectiveDate && endDate > effectiveDate ? Days360(effectiveDate, endDate) : startDate > effectiveDate && endDate > effectiveDate ? Days360(startDate, endDate) : 0; const rawMonthsInPeriod = (range360 / 360) * 12; // 先对显示字段四舍五入,再计算周期租金 const monthlyRent = Math.round(rawMonthlyRent); const monthsInPeriod = Math.round(rawMonthsInPeriod); const rentInPeriod = Math.round(monthlyRent * monthsInPeriod); return { description: scheduleData.description, monthlyRent, monthsInPeriod, rentInPeriod, }; }
内容的提问来源于stack exchange,提问作者Ananya Amar
相关产品推荐
相关产品推荐

