Home > Software engineering >  Node JS : Code to calculate number of working days in a month between two dates
Node JS : Code to calculate number of working days in a month between two dates

Time:12-14

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

  • Related