如何计算跨多个日期范围或部分在范围内的选中日期天数?
日期区间重叠天数计算问题解决方案
问题背景
当前代码仅能正确计算选中起止日期完全处于单个预设日期范围内的天数,无法处理以下两种场景:
- 选中日期同时覆盖两个预设范围(示例:2024年4月10日至4月17日,同时覆盖rangesInputRange2的4.1-4.14和rangesInputRange1的4.15-5.1)
- 选中日期仅部分落在单个预设范围内(示例:2024年8月28日至9月3日,仅8.28-8.31属于rangesInputRange2的7.1-8.31)
修改后的完整代码
var rangesInputRange1 = [ { startDate: parseDate("15/04/2024"), endDate: parseDate("01/05/2024") }, { startDate: parseDate("01/06/2024"), endDate: parseDate("30/06/2024") } ]; var rangesInputRange2 = [ { startDate: parseDate("01/04/2024"), endDate: parseDate("14/04/2024") }, { startDate: parseDate("01/07/2024"), endDate: parseDate("31/08/2024") } ]; function parseDate(dateString) { var parts = dateString.split("/"); return new Date(parts[2], parts[1] - 1, parts[0]); } // 计算两个日期区间的重叠天数(包含首尾日期) function calculateOverlapDays(selectedStart, selectedEnd, rangeStart, rangeEnd) { const overlapStart = new Date(Math.max(selectedStart.getTime(), rangeStart.getTime())); const overlapEnd = new Date(Math.min(selectedEnd.getTime(), rangeEnd.getTime())); // 无重叠时返回0 if (overlapStart > overlapEnd) return 0; const oneDay = 24 * 60 * 60 * 1000; // 天数计算需加1,因为包含起始和结束当天 return Math.round(Math.abs((overlapEnd - overlapStart) / oneDay)) + 1; } jQuery('#start-date, #end-date').on('change', function() { var startDate = parseDate(jQuery('#start-date').val()); var endDate = parseDate(jQuery('#end-date').val()); // 计算选中日期在range1中的总重叠天数 var daysInRange1 = 0; rangesInputRange1.forEach(range => { daysInRange1 += calculateOverlapDays(startDate, endDate, range.startDate, range.endDate); }); // 计算选中日期在range2中的总重叠天数 var daysInRange2 = 0; rangesInputRange2.forEach(range => { daysInRange2 += calculateOverlapDays(startDate, endDate, range.startDate, range.endDate); }); var inputRange1 = jQuery('input.checkbox1'); var inputNumber1 = jQuery('input.number1'); var inputRange2 = jQuery('input.checkbox2'); var inputNumber2 = jQuery('input.number2'); inputRange1.prop('checked', daysInRange1 > 0).trigger('change'); inputNumber1.val(daysInRange1).trigger('change'); inputRange2.prop('checked', daysInRange2 > 0).trigger('change'); inputNumber2.val(daysInRange2).trigger('change'); }); jQuery('#start-date, #end-date').trigger('change');
关键修改说明
- 新增
calculateOverlapDays函数:- 通过
Math.max和Math.min精准获取两个区间的重叠起止日期 - 先判断重叠起止是否有效(即是否存在实际重叠),无效则返回0
- 计算天数时加1,确保包含首尾两个日期(例如4.10到4.14共5天,差值计算为4天,加1后得到正确结果)
- 通过
- 重构天数计算逻辑:
- 遍历每个预设日期范围,逐个计算与选中区间的重叠天数并累加
- 彻底解决了跨多个预设区间、部分重叠的场景计算问题
内容的提问来源于stack exchange,提问作者kaqu
相关产品推荐
相关产品推荐

