/**
* Calculate working hours in a given time range. Does not take weekends into account.
* @param {Date} start start Date of range
* @param {Date} end end Date of range
* @param {number} whStart start of working hours
* @param {number} whEnd end of working hours
* @returns object containing total working hours in range and working hours per day in milliseconds (ms) and hours (h)
*/
function workingHoursInRange(start, end, whStart, whEnd) {
let totalTime = 0;
// get day difference between start and end date
const dayDiff = end.getDate() - start.getDate() + 1;
let diff = 0;
const workingHoursPerDay = [...Array(dayDiff)].map((_, i) => {
// first day (start time till end of working hours)
if (i === 0) diff = firstDay(start, whStart, whEnd);
// last day (start of working hours till end date)
else if (i === dayDiff - 1) diff = lastDay(end, whStart, whEnd);
// days inbetween are full days
else diff = (whEnd - whStart) * 1000 * 3600;
totalTime += diff;
return diff;
});
return {
workingHoursPerDay: {
ms: workingHoursPerDay,
h: workingHoursPerDay.map((it) => it / (1000 * 3600)),
},
totalHours: {
ms: totalTime,
h: totalTime / (1000 * 3600),
},
};
}
/**
* Calculate working hours on first day of a date range
* @param {Date} date date
* @param {number} whStart start of working hours
* @param {number} whEnd end of working hours
* @returns working hours in milliseconds
*/
function firstDay(date, whStart, whEnd) {
const minEnd = new Date(
date.getFullYear(),
date.getMonth(),
date.getDate(),
whEnd
);
const maxStart = new Date(
Math.max(
new Date(date.getFullYear(), date.getMonth(), date.getDate(), whStart),
date
)
);
return minEnd - maxStart;
}
/**
* Calculate working hours on last day of a date range
* @param {Date} date date
* @param {number} whStart start of working hours
* @param {number} whEnd end of working hours
* @returns working hours in milliseconds
*/
function lastDay(date, whStart, whEnd) {
const maxStart = new Date(
date.getFullYear(),
date.getMonth(),
date.getDate(),
whStart
);
const minEnd = new Date(
Math.min(
new Date(date.getFullYear(), date.getMonth(), date.getDate(), whEnd),
date
)
);
return minEnd - maxStart;
}
// Test
const workingHoursStart = 9;
const workingHoursEnd = 17;
const input = [
{
start: new Date("2022-04-25 01:00:00"),
end: new Date("2022-04-27 10:00:00"),
},
{
start: new Date("2022-04-25 12:00:00"),
end: new Date("2022-04-27 10:00:00"),
},
{
start: new Date("2022-04-26 12:33:00"),
end: new Date("2022-04-26 16:05:00"),
},
];
// calculate working hours for all ranges
const result = input.map(({ start, end }) =>
workingHoursInRange(start, end, workingHoursStart, workingHoursEnd)
);
// log result
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }