JS---计算请假时长,按大小周计算
JS计算请假时长:
<script type="text/javascript"> /** * 计算两个时间点之间的有效工作时间(单位:小时,保留2位小数) * @param {string|Date} startTime - 请假开始时间 * @param {string|Date} endTime - 请假结束时间 * @param {Array<{start: string, end: string}>} workShifts - 工作时间段数组(如 ["08:45-12:00", "13:30-18:00"]) * @param {number} [firstWorkdayOfWeek=1] - 大小周起始周(1=第1周上班,0=第1周休息) * @returns {number} 有效工作时间(小时) */ function calculateLeaveHours(startTime, endTime, workShifts, firstWorkdayOfWeek = 1) { /** * 判断是否是大小周的休息周六 * @param {Date} date - 要判断的日期 * @param {number} firstWorkdayOfWeek - 大小周起始周(1=第1周上班,0=第1周休息) * @returns {boolean} - 是否是休息周六 */ const isRestSaturday = function(date, firstWorkdayOfWeek) { if (date.getDay() !== 6) return false; // 不是周六,直接返回 false const year = date.getFullYear(); const month = date.getMonth(); const day = date.getDate(); // 获取当月第1天的日期 const firstDayOfMonth = new Date(year, month, 1); // 获取当月第1天是周几(0=周日,1=周一,...,6=周六) const firstDayWeekday = firstDayOfMonth.getDay(); // 计算当月第1个周六的日期 const firstSaturday = 1 + (5 - firstDayWeekday + 7) % 7; // 计算当前日期是当月的第几个周六 const daysSinceFirstSaturday = day - firstSaturday; const weekNumber = Math.floor(daysSinceFirstSaturday / 7) + 1; // 判断是否是休息周六(大小周逻辑) return (weekNumber + firstWorkdayOfWeek) % 2 === 0; } /** * 解析时间字符串("HH:mm")返回 Date 对象(当天时间) */ const parseTime = function(timeStr) { const [hours, minutes] = timeStr.split(":").map(Number); const date = new Date(); date.setHours(hours, minutes, 0, 0); return date; } const workPeriods = workShifts.map(shift => { const [start, end] = shift.split("-"); return { start: parseTime(start), end: parseTime(end) }; }); const startDate = new Date(startTime); const endDate = new Date(endTime); if (endDate <= startDate) return 0; let totalHours = 0; const currentDate = new Date(startDate); while (currentDate <= endDate) { const year = currentDate.getFullYear(); const month = currentDate.getMonth(); const day = currentDate.getDate(); // 判断是否是大小周的休息周六 if (isRestSaturday(currentDate, firstWorkdayOfWeek)) { currentDate.setDate(currentDate.getDate() + 1); continue; } // 判断是否是周日(无论大小周,周日都休息) if (currentDate.getDay() === 0) { currentDate.setDate(currentDate.getDate() + 1); continue; } // 计算当天的工作时间 const dayStart = new Date(year, month, day, 0, 0, 0); const dayEnd = new Date(year, month, day, 23, 59, 59); const actualStart = new Date(Math.max(startDate, dayStart)); const actualEnd = new Date(Math.min(endDate, dayEnd)); if (actualEnd <= actualStart) { currentDate.setDate(currentDate.getDate() + 1); continue; } // 计算当天所有工作时间段的有效时间 let dailyHours = 0; for (const period of workPeriods) { const periodStart = new Date(dayStart); periodStart.setHours( period.start.getHours(), period.start.getMinutes(), period.start.getSeconds() ); const periodEnd = new Date(dayStart); periodEnd.setHours( period.end.getHours(), period.end.getMinutes(), period.end.getSeconds() ); const validStart = new Date(Math.max(actualStart, periodStart)); const validEnd = new Date(Math.min(actualEnd, periodEnd)); if (validEnd > validStart) { dailyHours += (validEnd - validStart) / (1000 * 60 * 60); } } totalHours += dailyHours; currentDate.setDate(currentDate.getDate() + 1); } return parseFloat(totalHours.toFixed(2)); } // ===== 测试示例 ===== const workShifts = ["08:45-12:00", "13:30-18:00"]; // 测试大小周(第1周上班,第2周休息) // console.log(calculateLeaveHours("2024-01-06 09:00", "2024-01-06 17:00", workShifts, 1)); // 0 小时(第2周周六,休息) // console.log(calculateLeaveHours("2024-01-13 09:00", "2024-01-13 17:00", workShifts, 1)); // 7.25 小时(第3周周六,上班) // console.log(calculateLeaveHours("2024-01-20 09:00", "2024-01-20 17:00", workShifts, 1)); // 0 小时(第4周周六,休息) // 测试大小周(第1周休息,第2周上班) // console.log(calculateLeaveHours("2024-01-06 09:00", "2024-01-06 17:00", workShifts, 0)); // 7.25 小时(第2周周六,上班) // console.log(calculateLeaveHours("2024-01-13 09:00", "2024-01-13 17:00", workShifts, 0)); // 0 小时(第3周周六,休息) console.log(calculateLeaveHours("2025-08-08 08:45", "2025-08-08 12:00", workShifts, 1)); // 0 </script>
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号