I wanted to calculate the number of working days in each of the month, eg Oct'22 Nov'22, Dec'22 Jan'22 and Feb'22 for the resource when assigned between 20-Oct-22 to 22-Feb-22.
Currently I am able to calculate the number of working days in month using the below code. However not able to capture the working days in a month based on the Assigned Start date and End date.
const month = await db.sequelize.query(`(
SELECT month from financialmonths
where id= :id
)`, {
replacements: {
id: month_id
},
type: sequelize.QueryTypes.SELECT,
raw: true
})
let monthName = month[0].month
function getMonthNumberFromName(monthName) {
return new Date(`${monthName} 1, ${year}`).getMonth() 1;
}
const monthId = getMonthNumberFromName(monthName)
const days = moment(year " - " monthId, "YYYY-MM").monthBusinessDays()
let count = 0;
for (let key in days) {
count;
}
//calculating available STU
const cost_per_stu = bandCost.stu_convertor
const hours = count * 8;
const totalStu = cost_per_stu * hours;
const allocated_stus = (allocated_percentage / 100) * totalStu;
I tried using moment function, however not able to capture working days specific to each month based on given start date and end date.
CodePudding user response:
The simplest way to accomplish this is to search for these days between your start and end dates.
There's an additional verification to make sure that only working days from holidays
array are subtracted.
$(document).ready(() => {
$('#calc').click(() => {
var d1 = $('#d1').val();
var d2 = $('#d2').val();
$('#dif').text(workingDaysBetweenDates(d1,d2));
});
});
let workingDaysBetweenDates = (d0, d1) => {
/* Two working days and an sunday (not working day) */
var holidays = ['2016-05-03', '2016-05-05', '2016-05-07'];
var startDate = parseDate(d0);
var endDate = parseDate(d1);
// Validate input
if (endDate <= startDate) {
return 0;
}
// Calculate days between dates
var millisecondsPerDay = 86400 * 1000; // Day in milliseconds
startDate.setHours(0, 0, 0, 1); // Start just after midnight
endDate.setHours(23, 59, 59, 999); // End just before midnight
var diff = endDate - startDate; // Milliseconds between datetime objects
var days = Math.ceil(diff / millisecondsPerDay);
// Subtract two weekend days for every week in between
var weeks = Math.floor(days / 7);
days -= weeks * 2;
// Handle special cases
var startDay = startDate.getDay();
var endDay = endDate.getDay();
// Remove weekend not previously removed.
if (startDay - endDay > 1) {
days -= 2;
}
// Remove start day if span starts on Sunday but ends before Saturday
if (startDay == 0 && endDay != 6) {
days--;
}
// Remove end day if span ends on Saturday but starts after Sunday
if (endDay == 6 && startDay != 0) {
days--;
}
/* Here is the code */
holidays.forEach(day => {
if ((day >= d0) && (day <= d1)) {
/* If it is not saturday (6) or sunday (0), substract it */
if ((parseDate(day).getDay() % 6) != 0) {
days--;
}
}
});
return days;
}
function parseDate(input) {
// Transform date from text to date
var parts = input.match(/(\d )/g);
// new Date(year, month [, date [, hours[, minutes[, seconds[, ms]]]]])
return new Date(parts[0], parts[1]-1, parts[2]); // months are 0-based
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="d1" value="2016-05-02"><br>
<input type="text" id="d2" value="2016-05-08">
<p>Working days count: <span id="dif"></span></p>
<button id="calc">Calc</button>
<p>
Now it shows 5 days, but I need for example add holidays
3 and 5 May (2016-05-03 and 2016-05-05) so the result will be 3 working days
</p>
CodePudding user response:
const moment = require('moment');
const getWorkingDays = (startDate, endDate) => {
const start = moment(startDate);
const end = moment(endDate);
let workingDays = 0;
while (start <= end) {
if (start.day() !== 0 && start.day() !== 6) {
workingDays ;
}
start.add(1, 'days');
}
return workingDays;
}
I think it should work