前端计算请假时长

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 }

}

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值