ts 工作时间计算

2021年10月27日 ts

时间长度的计算

参数开始时间,结束时间,上午工作时间范围,下午工作时间范围、考勤范围(该版本的考勤范围为一周中的配置)

import dayjs from 'dayjs';
​
/**
 * 根据汉字变换成数字 0-周日
 * @param value
 */
const changeWeeks = (value: string[]): number[] => {
  const result: number[] = [];
  value.map((item) => {
    if (item === '周日') result.push(0);
    if (item === '周一') result.push(1);
    if (item === '周二') result.push(2);
    if (item === '周三') result.push(3);
    if (item === '周四') result.push(4);
    if (item === '周五') result.push(5);
    if (item === '周六') result.push(6);
  });
​
  return result;
};
​
/**
 * 是否在考勤范围
 * @param num
 * @param list
 * @returns
 */
const checkWeeks = (num: number, list: number[]): boolean => {
  return list.some((item) => item === num);
};
​
const diffDate = (
  start: string,
  end: string,
  startAm: string | null,
  endAm: string | null,
  startPm: string | null,
  endPm: string | null,
  weeks: string[] | null,
): number[] => {
  console.log(start, end, startAm, endAm, startPm, endPm, weeks);
  if (!(startAm && endAm && startPm && endPm && weeks)) return [0, 0];
  const daySecs = 24 * 60 * 60;
​
  // 返回小时数
  let totalTime = 0;
  // 返回天数
  let totaDay = 0;
​
  // 目标时间
  const startTime = dayjs(start);
  let tempTime = dayjs(start);
  const endTime = dayjs(end);
​
  const Total = endTime.diff(startTime, 'hours');
  // 上午工作时间 WAM
  const amStartTime = startAm.split(':');
  const amEndTime = endAm.split(':');
​
  // 上午开始工作时间 小时 分钟 WAM HM
  const amStartTimeH = parseInt(amStartTime[0]);
  const amStartTimeM = parseInt(amStartTime[1]);
​
  // 上午结束工作时间 小时 分钟 WAM HM
  const amEndTimeH = parseInt(amEndTime[0]);
  const amEndTimeM = parseInt(amEndTime[1]);
​
  // 下午工作时间 WPM
  const pmStartTime = startPm.split(':');
  const pmEndTime = endPm.split(':');
​
  // 下午开始工作时间 小时 分钟 WPM HM
  const pmStartTimeH = parseInt(pmStartTime[0]);
  const pmStartTimeM = parseInt(pmStartTime[1]);
​
  // 下午结束工作时间 小时 分钟 WPM HM
  const pmEndTimeH = parseInt(pmEndTime[0]);
  const pmEndTimeM = parseInt(pmEndTime[1]);
​
  // 工作时间 一周中的设置 WWEEK
  const weekTime = changeWeeks(weeks);
​
  // 开始时间的小时和分钟 MHM
  const startFH = startTime.hour();
  const startFM = startTime.minute();
​
  // 结束时间的小时和分钟 MHM
  const endNH = endTime.hour();
  const endNM = endTime.minute();
  while (
    Math.floor(tempTime.unix() / daySecs) <=
    Math.floor(endTime.unix() / daySecs)
  ) {
    if (checkWeeks(tempTime.get('day'), weekTime)) {
      //在考勤范围
      totaDay += 1;
      totalTime +=
        judgeSection(pmEndTimeH, pmEndTimeM) -
        judgeSection(pmStartTimeH, pmStartTimeM) +
        judgeSection(amEndTimeH, amEndTimeM) -
        judgeSection(amStartTimeH, amStartTimeM);
​
      if (
        Math.floor(tempTime.unix() / daySecs) ===
        Math.floor(startTime.unix() / daySecs)
      ) {
        // console.log('开始时间');
        if (
          judgeSection(startFH, startFM) <
          judgeSection(amStartTimeH, amStartTimeM)
        ) {
          //上班之前
        }
        if (
          judgeSection(startFH, startFM) >
            judgeSection(amStartTimeH, amStartTimeM) &&
          judgeSection(startFH, startFM) < judgeSection(amEndTimeH, amEndTimeM)
        ) {
          //上午工作时间
          totalTime =
            totalTime -
            (judgeSection(startFH, startFM) -
              judgeSection(amStartTimeH, amStartTimeM));
        }
        if (
          judgeSection(startFH, startFM) >
            judgeSection(amEndTimeH, amEndTimeM) &&
          judgeSection(startFH, startFM) <
            judgeSection(pmStartTimeH, pmStartTimeM)
        ) {
          // 午休时间
          totalTime =
            totalTime -
            (judgeSection(amEndTimeH, amEndTimeM) -
              judgeSection(amStartTimeH, amStartTimeM));
        }
        if (
          judgeSection(startFH, startFM) >
            judgeSection(pmStartTimeH, pmStartTimeM) &&
          judgeSection(startFH, startFM) < judgeSection(pmEndTimeH, pmEndTimeM)
        ) {
          //下午工作时间
          totalTime =
            totalTime -
            (judgeSection(startFH, startFM) -
              judgeSection(pmStartTimeH, pmStartTimeM) +
              judgeSection(amEndTimeH, amEndTimeM) -
              judgeSection(amStartTimeH, amStartTimeM));
        }
        if (
          judgeSection(startFH, startFM) >= judgeSection(pmEndTimeH, pmEndTimeM)
        ) {
          // 下班之后
          // 天数-1 并且时长减去一天
          totaDay = totaDay - 1;
          totalTime =
            totalTime -
            (judgeSection(pmEndTimeH, pmEndTimeM) -
              judgeSection(pmStartTimeH, pmStartTimeM) +
              judgeSection(amEndTimeH, amEndTimeM) -
              judgeSection(amStartTimeH, amStartTimeM));
        }
        // console.log(totaDay, totalTime);
      } else if (
        Math.floor(tempTime.unix() / daySecs) ===
        Math.floor(endTime.unix() / daySecs)
      ) {
        console.log('结束时间');
        console.log(
          judgeSection(endNH, endNM),
          judgeSection(amStartTimeH, amStartTimeM),
          judgeSection(amEndTimeH, amEndTimeM),
        );
        if (judgeSection(endNH, endNM) > judgeSection(pmEndTimeH, pmEndTimeM)) {
          // 结束时间晚于下班时间
        }
        if (
          judgeSection(endNH, endNM) < judgeSection(pmEndTimeH, pmEndTimeM) &&
          judgeSection(endNH, endNM) > judgeSection(pmStartTimeH, pmStartTimeM)
        ) {
          // 结束时间在下午工作范围
          console.log('结束时间在下午工作范围');
          totalTime =
            totalTime -
            (judgeSection(pmEndTimeH, pmEndTimeM) - judgeSection(endNH, endNM));
        }
        if (
          judgeSection(endNH, endNM) > judgeSection(amEndTimeH, amEndTimeM) &&
          judgeSection(endNH, endNM) < judgeSection(pmStartTimeH, pmStartTimeM)
        ) {
          // 午休时间
          console.log('午休时间');
          totalTime =
            totalTime -
            (judgeSection(pmEndTimeH, pmEndTimeM) -
              judgeSection(pmStartTimeH, pmStartTimeM));
        }
        if (
          judgeSection(endNH, endNM) >
            judgeSection(amStartTimeH, amStartTimeM) &&
          judgeSection(endNH, endNM) < judgeSection(amEndTimeH, amEndTimeM)
        ) {
          // 上午上班时间
          console.log('上午上班时间');
          totalTime =
            totalTime -
            (judgeSection(pmEndTimeH, pmEndTimeM) -
              judgeSection(pmStartTimeH, pmStartTimeM)) -
            (judgeSection(amEndTimeH, amEndTimeM) - judgeSection(endNH, endNM));
        }
        if (
          judgeSection(endNH, endNM) < judgeSection(amStartTimeH, amStartTimeM)
        ) {
          // 结束时间早于上午上班时间
          // console.log('203');
          console.log('结束时间早于上午上班时间');
          totaDay = totaDay - 1;
          totalTime =
            totalTime -
            (judgeSection(pmEndTimeH, pmEndTimeM) -
              judgeSection(pmStartTimeH, pmStartTimeM) +
              judgeSection(amEndTimeH, amEndTimeM) -
              judgeSection(amStartTimeH, amStartTimeM));
        }
      }
    }
​
    tempTime = tempTime.add(1, 'day');
  }
​
  /**
   * 总天数
   * 时长
   * 除去上班的时长 --- 加班时长(无加班范围)
   */
  const aDay =
    judgeSection(pmEndTimeH, pmEndTimeM) -
    judgeSection(pmStartTimeH, pmStartTimeM) +
    judgeSection(amEndTimeH, amEndTimeM) -
    judgeSection(amStartTimeH, amStartTimeM);
​
  totaDay = parseFloat((totalTime / aDay).toFixed(1));
  return [
    totaDay,
    parseFloat(totalTime.toFixed(1)),
    parseFloat((Total - totalTime).toFixed(1)),
  ];
};
​
function judgeSection(hours: number, mins: number) {
  const hourSecs = 60 * 60;
  const minSecs = 60;
  const section = hours * hourSecs + mins * minSecs;
  return section / hourSecs;
}
​
export default diffDate;
​

changeWeeks函数作用是将汉字的考勤期段转化为数字

checkWeeks函数作用是校验某天是否在考勤期段

diffDate函数计算时间

首先是while循环如果结束时间大于开始时间开始时间增加一天,计算的时间也增加一天,之后单独计算开始时间,开始时间早于上班之前不减,在上午工作时间期间开始则减去上午工作开始时间到输入的开始时间的范围、开始时间在午休期间则减去上午工作时长,其余都以此类推。

judgeSection函数作为计算小时加上分钟的总数单位是分钟,用来做比较。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值