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函数作为计算小时加上分钟的总数单位是分钟,用来做比较。