2

非常挣扎所以让我痛苦你一个场景:

餐厅的服务员每小时挣 15 美元,但在 21.00 到 02.30 之间,他每小时额外获得 3 美元的报酬。现在我所拥有的是作为 Date 对象的轮班的“开始”和“结束”,我想计算轮班中有多少小时的额外付费时间。(请记住开始和结束轮班时间可以是任何东西——而且它变得很困难)

我通过使用大量 if 语句使其工作,但这绝对不是正确的方法。我在这里添加我的代码链接,但它是一团糟,所以你知道(有两个不同的时间段,在该代码 fui 中有额外的报酬)。任何人都知道更好的计算方法吗?(任何可以在这里提供帮助的类?)

static calculateShiftSalary(shift: Shift, employee: Employee): Shift {
    const extraPaidStart = 22
    const extraPaidEnd= 2.5 // meaning 02.30 o'clock -of the next day here

    let start:Date = shift.startDate
    let end:Date = shift.endDate

    let extraHours:number = 
          getNumberOfExtraPaidHours(start,end,extraPaidStart,extraPaidEnd)
}

因此,如果 U'd 在 20.00 和 23.30 ->'extraHours'=1,5 之间转换,并且如果转换在 23.00 和 02.00 ->extraHours=3h 之间

如果有任何帮助,extraPaidStart 和 extraPaidEnd 可以更改为 Date ofc (y)

4

1 回答 1

1

让我们先来看最简单的情况:我们的工人只工作了一天。一个时间表是额外的时间一夜之间看起来是这样的:

extra paid ---|-- regular paying ---------|---- extra paid ---
      |--------- working time -----------------------------|
      |--- 1 -------|--------------- 2 ----------------|---- 3 ---|

如果额外的时间只是一天,实际上更简单:

|----------- regular paying -------|------ extra paid ----|----|
    |------ working time -----------------|
    |-----  1 -----------------------------|- 2 -|

所以我们只需要计算工人工作的三个不同范围,所有单位都以分钟为单位:

 function paymentRange(payment: number, start: number, end: number) {
    return function calculatePayment(startWorking: number, endWorking: number) {
      if(start < end) { 
        const rangeStart = Math.max(start, startWorking);
        const rangeEnd = Math.min(end, endWorking);
        return Math.max(rangeEnd - rangeStart, 0) / 60 * payment;
    } else {
       const morning =  Math.max(end - startWorking, 0);
       const evening = Math.max(endWorking - start, 0)
       return (morning + evening) / 60 * payment;
  }
 }
}

现在我们只需要一种组合多种付款的方法:

 function combinedPayment(...payments) {
   return (start, end) => payments.reduce((sum, payment) => sum + payment(start, end), 0);
 }

因此,要获得一天的付款,我们可以这样做:

 const calculatePayment = combinedPayment(
   paymentRange(3/*$*/, 22/*h*/ * 60, 2/*h*/ * 60 + 30/*min*/),
   paymentRange(15/*$*/, 0/*min*/, 24/*h*/ * 60)
);

 // If he worked from 1h to 22h:
calculatePayment(1/*h*/ * 60, 22/*h*/ * 60)

现在我们只需要将日期范围划分为天数,然后计算天数的付款:

 const dateToMins = date => date.getHours() * 60 + date.getMinutes();

const toWholeDay = date => new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
const min = (a, b) => new Date(Math.min(+a, +b));
const max = (a, b) => new Date(Math.max(+a, +b));

 function paymentForDateRange(payment, start: Date, end: Date) {
  let pay = 0;
  let today = toWholeDay(start);
  while(+today < +end) {
    const nextDay = new Date(today + 1000 * 60 * 60 * 24);
    const startWorking = max(start, today);
    const endWorking = min(end, nextDay);
    pay += payment(dateToMins(startWorking), dateToMins(endWorking));
   today = nextDay;
  }
  return pay;
}

所以我们终于可以做到:

paymentForDateRange(calculatePayment, new Date(), new Date())

PS:我无法测试其中的每一个部分,它可能无法完全工作

于 2018-05-21T12:30:02.813 回答