最近在优化一个办公系统,需要计算请假时间
首先要实现请假时间的计算,需要以下几步
第一步、首先我们要知道时间表(我们以最常用的 上午上班时间(09:00 - 12:00)下午(13:00 - 18:00)为例)
第二步,我们分析可能出现的可能性
1、早上请假
2、下午请假
3、跨中午请假
4、跨天但又不满一天请假
5、跨天满一天请假
6、跨周请假(需要除去周末)
7、节假日请假 (需要除去节假日)---一般节假日是预设的,这个功能暂时没有实现
第三步:细分析
我们发现,在当请假不满一天的时候,早上请假和下午请假都是在上班时间内,这样我们直接用下午时间减去上午时间就行,所以,上午请假和下午请假一共可以归为一类:所以一共可能有一下几种情况:
1、早上请假,下午请假
2、跨中午请假
3、跨天但又不满一天请假
4、跨天满一天请假
5、跨周请假(需要除去周末)
6、节假日请假 (需要除去节假日)---一般节假日是预设的,这个功能暂时没有实现
第四步:我们还需要考虑。年假 病假 事假 抵扣等各种情况
第五步:直接上代码
计算时间代码:
// 计算两段时间工作日工时 calculate (startTime, endTime) { if (startTime >= endTime) { return 0 } const lastDay = this.getLastDay(endTime.getFullYear(), endTime.getMonth() + 1) startTime = this.carryTime(startTime) endTime = this.carryTime(endTime) let totalTime = 0 if (startTime.getDay() === 6 || startTime.getDay() === 0) { totalTime = endTime.getDate() - startTime.getDate() } else { totalTime = Math.floor(((endTime - startTime) / (3600 * 1000)) / 24) } const tempStartTime = new Date() tempStartTime.setTime(startTime.getTime()) let temp = 0 if (endTime.getDate() === lastDay) { while (tempStartTime.getDate() <= endTime.getDate()) { if (tempStartTime.getDay() === 6 && tempStartTime.getDay() === 0) { totalTime-- } tempStartTime.setDate(tempStartTime.getDate() + 1) if (tempStartTime.getDate() === 31) { break } } } else { while (tempStartTime.getDate() <= endTime.getDate()) { if (tempStartTime.getDay() === 6 || tempStartTime.getDay() === 0) { totalTime-- } tempStartTime.setDate(tempStartTime.getDate() + 1) } } if (startTime.getHours() <= 12 && endTime.getHours() >= 13) { temp += -0.1 } if (startTime.getHours() * 60 + startTime.getMinutes() !== endTime.getHours() * 60 + endTime.getMinutes()) { do { if (startTime.getDay() === 6 || startTime.getDay() === 0) { startTime.setDate(startTime.getDate() + 1) startTime.setHours(9) startTime.setMinutes(0) continue } if (startTime.getHours() * 60 + startTime.getMinutes() >= 9 * 60 && startTime.getHours() * 60 + startTime.getMinutes() < 18 * 60) { temp += 0.05 } startTime.setTime(startTime.getTime() + 0.5 * 3600 * 1000) } while (startTime.getHours() * 60 + startTime.getMinutes() !== endTime.getHours() * 60 + endTime.getMinutes()) } totalTime += Math.floor(temp / 0.8) totalTime += temp % 0.8 totalTime = Math.round(totalTime * 100) / 100 const days = Math.floor(totalTime) const hours = Math.round((totalTime - days) * 100) / 10 const duration = days * 8 + hours return duration }, carryTime (date) { if (date.getMinutes() > 0 && date.getMinutes() < 15) { date.setMinutes(0) } if (date.getMinutes() >= 15 && date.getMinutes() < 30) { date.setMinutes(30) } if (date.getMinutes() > 30 && date.getMinutes() < 45) { date.setMinutes(30) } if (date.getMinutes() >= 45) { date.setHours(date.getHours() + 1) date.setMinutes(0) } return date }, // 获取每个月最后一天 getLastDay (year, month) { let new_year = year // 取当前的年份 let new_month = month++// 取下一个月的第一天,方便计算(最后一天不固定) if (month > 12) { // 如果当前大于12月,则年份转到下一年 new_month -= 12 // 月份减 new_year++ // 年份增 } const new_date = new Date(new_year, new_month, 1) return (new Date(new_date.getTime() - 1000 * 60 * 60 * 24)).getDate()// 获取当月最后一天日期 },
年假事假抵扣代码:
timeCheck () { const totalHours = this.dateDiff / (3600 * 1000) switch (this.levelForm.type) { case 1: { // 年假 // 不足半天按半天计算, // 超过半天按一天计算 return this.annualLeave >= (totalHours / 8) } case 2: { // 病假 // 不足半天按半天计算, // 超过半天按一天计算 return this.sickLeave >= (totalHours / 8) } case 3: // 事假 return true case 4: { // 抵扣 return this.deduction >= totalHours } default: return false } }
大体界面如下:
时间间隔为半小时,年假必须时长必须半天或以上才行(这个element 有详细介绍我就不说了)