js---计算加班时长
使用js计算两个时间戳的加班时长:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script type="text/javascript"> /** * 计算加班时长 * @param {number} startTimeStamp - 开始时间戳(毫秒) * @param {number} endTimeStamp - 结束时间戳(毫秒) * @param {Array<string>} workShifts - 白天有效加班时段数组,如 ["08:45-12:00", "13:30-18:00"] * @returns {number} 加班总时长(小时,保留两位小数) */ function calculateOvertime(startTimeStamp, endTimeStamp, workShifts = ["08:45-12:00", "13:30-18:00"]) { // 参数校验 if (isNaN(startTimeStamp) || isNaN(endTimeStamp) || startTimeStamp >= endTimeStamp) { return 0; } // 将时间字符串转换为小时和分钟对象 const parseTimeToDate = function(timeStr){ const [hours, minutes] = timeStr.split(':').map(Number); return { hours, minutes }; } // 判断是否为节假日 const isHoliday = function(date){ // 示例:简单判断周末(实际项目中应该有更完整的节假日判断) const day = date.getDay(); return false; // day === 0 || day === 6; // 周日或周六 } // 计算单日的加班时间(返回分钟) const calculateDailyOvertime = function(start, end, workSegments, isWorkDay){ let dailyMinutes = 0; // 如果是工作日,先计算白天有效加班时段 if (isWorkDay) { for (const segment of workSegments) { const segmentStart = new Date(start); segmentStart.setHours(segment.start.hours, segment.start.minutes, 0, 0); const segmentEnd = new Date(start); segmentEnd.setHours(segment.end.hours, segment.end.minutes, 0, 0); // 计算与加班时段的交集 const overlapStart = new Date(Math.max(start, segmentStart)); const overlapEnd = new Date(Math.min(end, segmentEnd)); if (overlapStart < overlapEnd) { dailyMinutes += (overlapEnd - overlapStart) / (1000 * 60); } } } // 计算夜间加班时间(18:00之后或全天加班中的非白天时段) const nightStart = new Date(start); if (isWorkDay) { // 工作日的夜间加班从18:00或加班开始时间(如果晚于18:00)开始 const workDayEnd = new Date(start); workDayEnd.setHours(18, 0, 0, 0); nightStart.setTime(Math.max(start, workDayEnd)); } else { // 非工作日(周末/节假日)全天都算加班 nightStart.setTime(start); } const nightEnd = new Date(Math.min(end, new Date(start).setHours(23, 59, 59, 999))); if (nightStart < nightEnd) { dailyMinutes += (nightEnd - nightStart) / (1000 * 60); } return dailyMinutes; } // 将白天工作时段转换为时间对象数组 const workSegments = workShifts.map(segment => { const [startStr, endStr] = segment.split('-'); return { start: parseTimeToDate(startStr), end: parseTimeToDate(endStr) }; }); const startDate = new Date(startTimeStamp); const endDate = new Date(endTimeStamp); // 如果结束时间是第二天凌晨,需要特殊处理 const isOvernight = endDate.getDate() !== startDate.getDate(); let totalMinutes = 0; let currentDate = new Date(startDate); // 处理跨天的情况 while (currentDate < endDate) { const isWorkDay = !isHoliday(currentDate); // 这里可以添加节假日判断逻辑 const isSameDayAsStart = currentDate.getDate() === startDate.getDate(); const isSameDayAsEnd = currentDate.getDate() === endDate.getDate(); // 确定当天的开始和结束时间 const dayStart = new Date(currentDate); dayStart.setHours(0, 0, 0, 0); const dayEnd = new Date(dayStart); dayEnd.setDate(dayEnd.getDate() + 1); const segmentStart = isSameDayAsStart ? startDate : dayStart; const segmentEnd = isSameDayAsEnd ? endDate : dayEnd; // 计算当天的加班时间 totalMinutes += calculateDailyOvertime(segmentStart, segmentEnd, workSegments, isWorkDay); // 移动到下一天 currentDate.setDate(currentDate.getDate() + 1); } // 转换为小时并保留两位小数 return parseFloat((totalMinutes / 60).toFixed(2)); } // 使用示例 const start = new Date('2025-09-03T08:45:00').getTime(); // 周五晚上8点 const end = new Date('2025-09-03T18:00:00').getTime(); // 周六凌晨2点30分 const daySegments = ["08:45-12:00", "13:30-18:00"]; const overtimeHours = calculateOvertime(start, end, daySegments); console.log(`加班时长: ${overtimeHours} 小时`); // 输出如 "6.50 小时" </script> </body> </html>
打完收工!

浙公网安备 33010602011771号