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>

打完收工!

 
posted @ 2025-09-03 23:10  帅到要去报警  阅读(10)  评论(0)    收藏  举报