const dayjs = require('dayjs')
const customParseFormat = require('dayjs/plugin/customParseFormat')
dayjs.extend(customParseFormat)
const rest = true // 是否减去午休时间
// 上下班时间
const startWorkTime = '08:00'
const endWorkTime = '17:00'
// 午休息时间
const startFreeTime = '12:00'
const endFreeTime = '13:00'
export const getTotal = (options) => {
const holidayList = options?.holiday// 当年假期
// 是否过滤午休时间,默认是跳过,可自行修改
// {
// 请假开始时间
// beginAt,
// 请假结束时间
// endAt,
// }
// 这里做了开始和结束时间的调换,也可以直接 return 根据业务自行选择
if (dayjs(options.beginAt).isAfter(dayjs(options.endAt))) { [options.beginAt, options.endAt] = [options.endAt, options.beginAt] }
const restList = holidayList.map(d => dayjs(d, 'YYYY-MM-DD HH:mm'))
let minute = 0
const diffDay = dayjs(options.endAt)
.startOf('d').diff(dayjs(options.beginAt).startOf('d'), 'd')
for (let i = 0; i <= diffDay; i++) {
const day = dayjs(options.beginAt).add(i, 'd').startOf('d')
if (restList.some(d => d.isSame(day, 'd'))) continue
// 上午上班时间
const a = dayjs(`${day.format('YYYY-MM-DD')} ${startWorkTime}`,
'YYYY-MM-DD HH:mm')
// 下午下班时间
const f = dayjs(`${day.format('YYYY-MM-DD')} ${endWorkTime}`,
'YYYY-MM-DD HH:mm')
// 上午午休开始时间
const ar = dayjs(`${day.format('YYYY-MM-DD')} ${startFreeTime}`,
'YYYY-MM-DD HH:mm')
// 下午午休结束时间
const fr = dayjs(`${day.format('YYYY-MM-DD')} ${endFreeTime}`,
'YYYY-MM-DD HH:mm')
let beginAt = dayjs(options.beginAt)
beginAt = beginAt.isBefore(a) ? a : beginAt.isAfter(f) ? f : beginAt
let endAt = dayjs(options.endAt)
endAt = endAt.isAfter(f) ? f : endAt
if (rest) {
beginAt = beginAt.isAfter(ar) && beginAt.isBefore(fr) ? fr : beginAt
endAt = endAt.isAfter(ar) && endAt.isBefore(fr) ? ar : endAt
}
let ranges = []
if (diffDay === 0) {
if (rest && beginAt.isBefore(ar) && endAt.isAfter(fr)) {
ranges = [[beginAt, ar], [fr, endAt]]
} else {
ranges = [[beginAt, endAt]]
}
} else if (i === 0) {
if (rest) {
ranges = beginAt.isBefore(ar)
? [[beginAt, ar], [fr, f]]
: [[beginAt, f]]
} else {
ranges = [[beginAt, f]]
}
} else if (i === diffDay) {
if (rest) {
ranges = endAt.isBefore(ar) ? [[a, endAt]] : [[a, ar], [fr, endAt]]
} else {
ranges = [[a, endAt]]
}
} else {
if (rest) {
ranges = [[a, ar], [fr, f]]
} else {
ranges = [[a, f]]
}
}
minute += ranges.map(range => {
const diff = range[1].diff(range[0], 'minute')
if (diff < 0) {
return 0
}
return diff
}).reduce((a, b) => a + b, 0)
}
console.log(minute)
const oh = parseFloat((minute / 60).toFixed(2))
const d = oh % 8 > 0
? oh % 8 <= 4
? Math.floor(oh / 8) + 0.5
: Math.floor(oh / 8) + 1
: oh / 8
// oh 为原始时长, d 是按照 >0 但是<0.5 按 0.5天算,>0.5 按1天算,h是由天折算的请假时长
return { oh, d, h: d * 8 }
}