根据需求请假时间要排除法定节假日和非工作时间

1.获取当年的节假日

节假日是每年更新的,没有固定接口,需要手动录入

个人根据官方的节假日整理了当年的所有节假日,可以根据个人需求进行修改

// 获取每个月的节假日,如果当月没有节假日就默认星期六星期天
holidays: [
      [1, 2, 3, 10, 11, 17, 18, 24, 25, 31],// 1月
      [1, 7, 8, 15, 16, 17, 18, 19, 20, 21, 22, 23],// 2月
      [],// 3月
      [4, 5, 6, 11, 12, 18, 19, 25, 26],// 4月
      [1, 2, 3, 4, 5, 10, 16, 17, 23, 24, 30, 31],// 5月
      [6, 7, 13, 14, 19, 20, 21, 27, 28],// 6月
      [],// 7月
      [],// 8月
      [5, 6, 12, 13, 19, 25, 26, 27],// 9月
      [1, 2, 3, 4, 5, 6, 7, 11, 17, 18, 24, 25, 31],// 10月
      [],// 11月
      [],// 12月
    ]

2.使用当年的节假日进行判断

这里是封装的计算方法,传入开始时间和结束时间 时间格式为:年-月-日 时:分

里面定义了上班开始结束时间和中午休息时间,可以自定义

    // 计算工作时间调休小时数
    calculateLeaveTime(startTime, endTime) {
      const workStartHour = 9; // 工作开始时间 09:00
      const workEndHour = 18; // 工作结束时间 18:00
      const restStartHour = 12; // 午休开始 12:00
      const restEndHour = 13; // 午休结束 13:00

      const start = new Date(startTime);
      const end = new Date(endTime);

      if (end <= start) {
        this.tips = true;
        return "0小时";
      }

      let totalHours = 0;
      let current = new Date(start);
      current.setHours(0, 0, 0, 0); // 从当天0点开始

      const endDate = new Date(end);
      endDate.setHours(0, 0, 0, 0);

      // 处理每一天
      while (current <= endDate) {
        const currentDate = new Date(current);

        // 首先检查是否是工作日
        if (!this.isWorkDay(currentDate)) {
          current.setDate(current.getDate() + 1);
          continue;
        }

        // 如果是同一天
        if (
          this.isSameDay(currentDate, start) &&
          this.isSameDay(currentDate, end)
        ) {
          totalHours += this.calculateHoursForSameDay(
            start,
            end,
            workStartHour,
            workEndHour,
            restStartHour,
            restEndHour
          );
        }
        // 第一天
        else if (this.isSameDay(currentDate, start)) {
          totalHours += this.calculateHoursForFirstDay(
            start,
            workStartHour,
            workEndHour,
            restStartHour,
            restEndHour
          );
        }
        // 最后一天
        else if (this.isSameDay(currentDate, end)) {
          totalHours += this.calculateHoursForLastDay(
            end,
            workStartHour,
            workEndHour,
            restStartHour,
            restEndHour
          );
        }
        // 中间完整工作日
        else {
          totalHours += this.calculateFullWorkDayHours(
            workStartHour,
            workEndHour,
            restStartHour,
            restEndHour
          );
        }

        // 增加一天
        current.setDate(current.getDate() + 1);
      }

      this.tips = false;
      return parseFloat(totalHours.toFixed(1)) + "小时";
    },

    // 辅助方法
    isSameDay(date1, date2) {
      return (
        date1.getFullYear() === date2.getFullYear() &&
        date1.getMonth() === date2.getMonth() &&
        date1.getDate() === date2.getDate()
      );
    },

    isWorkDay(date) {
      const day = date.getDay();
      const month = date.getMonth();
      const dateNum = date.getDate();

      // 检查周末
      if (day === 0 || day === 6) {
        return false;
      }

      // 检查节假日
      const holidayArr = this.$store.state.holidays[month];
      if (holidayArr && holidayArr.includes(dateNum)) {
        return false;
      }

      return true;
    },

    calculateHoursForSameDay(
      start,
      end,
      workStart,
      workEnd,
      restStart,
      restEnd
    ) {
      const startHour = start.getHours() + start.getMinutes() / 60;
      const endHour = end.getHours() + end.getMinutes() / 60;

      // 调整到工作时间范围内
      const adjustedStart = Math.max(startHour, workStart);
      const adjustedEnd = Math.min(endHour, workEnd);

      if (adjustedEnd <= adjustedStart) return 0;

      // 计算总时长,扣除午休时间
      let total = adjustedEnd - adjustedStart;

      // 如果时间段跨越午休,扣除午休时间
      if (adjustedStart < restEnd && adjustedEnd > restStart) {
        const overlapStart = Math.max(adjustedStart, restStart);
        const overlapEnd = Math.min(adjustedEnd, restEnd);
        total -= Math.max(0, overlapEnd - overlapStart);
      }

      return Math.max(0, total);
    },

    calculateHoursForFirstDay(start, workStart, workEnd, restStart, restEnd) {
      const startHour = start.getHours() + start.getMinutes() / 60;
      const adjustedStart = Math.max(startHour, workStart);
      const adjustedEnd = workEnd;

      if (adjustedEnd <= adjustedStart) return 0;

      let total = adjustedEnd - adjustedStart;

      if (adjustedStart < restEnd && adjustedEnd > restStart) {
        const overlapStart = Math.max(adjustedStart, restStart);
        const overlapEnd = Math.min(adjustedEnd, restEnd);
        total -= Math.max(0, overlapEnd - overlapStart);
      }

      return Math.max(0, total);
    },

    calculateHoursForLastDay(end, workStart, workEnd, restStart, restEnd) {
      const endHour = end.getHours() + end.getMinutes() / 60;
      const adjustedStart = workStart;
      const adjustedEnd = Math.min(endHour, workEnd);

      if (adjustedEnd <= adjustedStart) return 0;

      let total = adjustedEnd - adjustedStart;

      if (adjustedStart < restEnd && adjustedEnd > restStart) {
        const overlapStart = Math.max(adjustedStart, restStart);
        const overlapEnd = Math.min(adjustedEnd, restEnd);
        total -= Math.max(0, overlapEnd - overlapStart);
      }

      return Math.max(0, total);
    },

    calculateFullWorkDayHours(workStart, workEnd, restStart, restEnd) {
      // 完整工作日时长 = (工作结束-工作开始) - 午休时长
      return workEnd - workStart - (restEnd - restStart);
    },

这里按每天八小时计算,排除了2024年法定节假日 劳动节的调休 一共使用了工作时间的32小时

3.计算当月工作日时间进度

// 计算工作日时间进度
            // 获取当前时间
            const now = new Date();
            // 获取当前年份和月份
            const currentYear = now.getFullYear();
            const currentMonth = now.getMonth();
            // 获取vuex里面存储的节假日
            let holidays = this.$store.state.holidays[currentMonth]
            // console.log("当月节假日", holidays);
            // 计算当月天数
            const daysInMonth = new Date(currentYear, currentMonth + 1, 0).getDate();
            // 当月几号
            const dayOfMonth = now.getDate();
            //  console.log("当月天数:", daysInMonth);
            //  console.log("当月的第", dayOfMonth, "天");
            // 工作日天数
            let workday = 0;
            // 当前工作日天数
            let Month = 0;
            // 当前时间进度
            let num = "0%";
            // 判断是否设置节假日
            if (holidays.length) {
                // 自定义节假日
                workday = daysInMonth - holidays.length;
                // console.log("自定义工作日", workday);
                // 默认已工作日
                for (let i = 1; i < dayOfMonth + 1; i++) {
                    if (!holidays.includes(i)) {
                        Month++;
                    }
                }
                num = Month / workday;
            } else {
                // 循环默认天数
                for (let i = 1; i < daysInMonth + 1; i++) {
                    let date = new Date(
                        new Date().getFullYear(),
                        new Date().getMonth(),
                        i
                    );
                    // 遍历每天获取星期几
                    let x = date.getDay();
                    // 不是节假日工作日就加一
                    if (![0, 6].includes(x)) {
                        workday++;
                    }
                }
                //  console.log("默认工作日", workday);
                // 默认已工作日
                for (let i = 1; i < dayOfMonth + 1; i++) {
                    let date = new Date(
                        new Date().getFullYear(),
                        new Date().getMonth(),
                        i
                    );
                    // 遍历每天获取星期几
                    let x = date.getDay();
                    // 不是节假日工作日就加一
                    if (![0, 6].includes(x)) {
                        Month++;
                    }
                }
                num = Month / workday;
            }
            // console.log("已工作", Month, "天");
            // console.log("时间进度" + (num * 100).toFixed(1) + "%");
            // 赋值时间进度
            this.less_day = (num * 100).toFixed(1).replace(/\.0$/, "") + "%";

计算当月工作日时间进度_const daysinmonth-CSDN博客文章浏览阅读242次。/ 获取当前时间// 获取当前年份和月份// 计算当月天数// 当月几号// console.log("当月天数:", daysInMonth);// console.log("当月的第", dayOfMonth, "天");// 工作日天数// 当前工作日天数// 当前时间进度// 自定义节假日// console.log("自定义工作日", workday);// 默认已工作日i++) {if (!Month++_const daysinmonth https://blog.csdn.net/weixin_70563937/article/details/134311477

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐