非常努力让我痛苦一个场景:
餐厅的服务员每小时收入15美元,但在21.00和02.30之间,他获得额外3美元/小时的报酬。现在我拥有的是“开始”#39;并且'结束'作为日期 - 对象的转变,我想计算在转移中多少小时的额外付费期间(如果有的话)。(记住转变的开始和结束时间可以是任何东西 - 并且它得到的bc很难)我通过使用大量的if语句使其工作,但这绝对不是正确的做法。我在这里添加了我的代码link但是它只是一团糟所以你知道(在代码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)
答案 0 :(得分: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:我无法测试它的每一部分,它可能无法完全发挥作用