如何用Laravel/JavaScript获取年度公假日并计算不含节假日的工作日天数
解决方案:计算排除周末与公假日的工作日天数
一、实现指定年份的公假日列表函数
不同国家/地区的公假日规则差异很大,以下以中国公假日为例提供可扩展的实现模板,你需要根据本国规则修改内容。该函数返回指定年份的所有公假日(含补休日)的Date对象数组:
function getPublicHolidays(year) { const holidays = []; // 1. 添加固定日期的公假日(根据本国规则修改) holidays.push(new Date(year, 0, 1)); // 元旦 holidays.push(new Date(year, 4, 1)); // 劳动节 holidays.push(new Date(year, 9, 1)); // 国庆节(示例取10.1,实际可添加10.1-10.7) // 2. 添加需要计算的浮动公假日(示例:中国清明节为公历4月4/5日,可根据年份调整) const qingMingDay = year % 4 === 0 ? 5 : 4; holidays.push(new Date(year, 3, qingMingDay)); // 3. 处理补休规则:若假日落在周末,添加对应补休日 holidays.forEach(holiday => { const dayOfWeek = holiday.getDay(); if (dayOfWeek === 0) { // 周日,补周一 holidays.push(new Date(holiday.getTime() + 86400000)); } else if (dayOfWeek === 6) { // 周六,补周五 holidays.push(new Date(holiday.getTime() - 86400000)); } }); // 去重并按日期排序 return [...new Set(holidays.map(date => date.toISOString()))] .map(str => new Date(str)) .sort((a, b) => a - b); }
注意:如果本国包含农历假日(如春节、中秋),可以引入成熟的农历转换库(如
lunar-javascript)来获取对应公历日期,避免自行实现复杂的转换逻辑。
二、修改原函数,加入公假日排除逻辑
在你已有的周末排除代码基础上,新增逻辑:计算日期区间内的工作日公假日数量,并从结果中扣除:
function getBusinessDateCount(startDate, endDate) { // 确保起始日期不晚于结束日期 if (startDate > endDate) { [startDate, endDate] = [endDate, startDate]; } var elapsed, daysBeforeFirstSunday, daysAfterLastSunday; var ifThen = function (a, b, c) { return a == b ? c : a; }; // 原有的周末排除计算逻辑 elapsed = endDate - startDate; elapsed /= 86400000; // 转换为天数 daysBeforeFirstSunday = (7 - startDate.getDay()) % 7; daysAfterLastSunday = endDate.getDay(); elapsed -= (daysBeforeFirstSunday + daysAfterLastSunday); elapsed = (elapsed / 7) * 5; elapsed += ifThen(daysBeforeFirstSunday - 1, -1, 0) + ifThen(daysAfterLastSunday, 6, 5); // 新增:计算区间内的工作日公假日数量 const yearStart = startDate.getFullYear(); const yearEnd = endDate.getFullYear(); let allHolidays = []; // 获取日期范围覆盖的所有年份的公假日 for (let year = yearStart; year <= yearEnd; year++) { allHolidays = [...allHolidays, ...getPublicHolidays(year)]; } // 筛选出在区间内、且不是周末的公假日(周末已被原逻辑排除) const workdayHolidays = allHolidays.filter(holiday => { return holiday >= startDate && holiday <= endDate && holiday.getDay() !== 0 && holiday.getDay() !== 6; }); // 扣除工作日公假日天数,确保结果不为负数 elapsed -= workdayHolidays.length; return Math.max(Math.ceil(elapsed), 0); }
三、优化事件处理代码(可选)
保留原有的交互逻辑,新增日期有效性验证,避免无效输入:
$(document).ready(function(){ $(document).on('change','#date2',function (evt) { let startStr = document.querySelector('#date1').value, endStr = document.querySelector('#date2').value; // 验证日期是否有效 const startDate = new Date(startStr); const endDate = new Date(endStr); if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) { document.getElementById("days").value = "请输入有效的日期"; return; } const result = getBusinessDateCount(startDate, endDate); document.getElementById("days").value = result + " Jours"; }); });
内容的提问来源于stack exchange,提问作者rajah
相关产品推荐
相关产品推荐

