How to calculate the number of working days between two dates in JavaScript using moment.js. I have a working formula that calculate these days, but the formula does not satisfies all conditions:

here is my code:

```
var start= moment(data[x].start_date);
var end= moment(data[x].est_end_date);
var difference= end.diff(start, 'days');
var workingDays= Math.round((difference/7)*5);
//data[x] is for iterating over a loop
```

I get five days per 7 days here because saturday and sunday are considered as NON-Working days, but this formula will fail if the count of the days were started from sunday or saturday.

Please any one could help in this regard that what necessary changes must be done in order to avoid this problem.

Just divide it into 3 parts.. first week, last week and the in between, something like this:

```
function workday_count(start,end) {
var first = start.clone().endOf('week'); // end of first week
var last = end.clone().startOf('week'); // start of last week
var days = last.diff(first,'days') * 5 / 7; // this will always multiply of 7
var wfirst = first.day() - start.day(); // check first week
if(start.day() == 0) --wfirst; // -1 if start with sunday
var wlast = end.day() - last.day(); // check last week
if(end.day() == 6) --wlast; // -1 if end with saturday
return wfirst + Math.floor(days) + wlast; // get the total
} // ^ EDIT: if days count less than 7 so no decimal point
```

The test code

```
var ftest = {date:'2015-02-0',start:1,end:7};
var ltest = {date:'2015-02-2',start:2,end:8};
var f = 'YYYY-MM-DD';
for(var z=ftest.start; z<=ftest.end; ++z) {
var start = moment(ftest.date + z);
for(var y=ltest.start; y<=ltest.end; ++y) {
var end = moment(ltest.date + y);
var wd = workday_count(start,end);
console.log('from: '+start.format(f),'to: '+end.format(f),'is '+wd+' workday(s)');
}
}
```

Output of test code:

```
from: 2015-02-01 to: 2015-02-22 is 15 workday(s)
from: 2015-02-01 to: 2015-02-23 is 16 workday(s)
from: 2015-02-01 to: 2015-02-24 is 17 workday(s)
from: 2015-02-01 to: 2015-02-25 is 18 workday(s)
from: 2015-02-01 to: 2015-02-26 is 19 workday(s)
from: 2015-02-01 to: 2015-02-27 is 20 workday(s)
from: 2015-02-01 to: 2015-02-28 is 20 workday(s)
from: 2015-02-02 to: 2015-02-22 is 15 workday(s)
from: 2015-02-02 to: 2015-02-23 is 16 workday(s)
from: 2015-02-02 to: 2015-02-24 is 17 workday(s)
from: 2015-02-02 to: 2015-02-25 is 18 workday(s)
from: 2015-02-02 to: 2015-02-26 is 19 workday(s)
from: 2015-02-02 to: 2015-02-27 is 20 workday(s)
from: 2015-02-02 to: 2015-02-28 is 20 workday(s)
from: 2015-02-03 to: 2015-02-22 is 14 workday(s)
from: 2015-02-03 to: 2015-02-23 is 15 workday(s)
from: 2015-02-03 to: 2015-02-24 is 16 workday(s)
from: 2015-02-03 to: 2015-02-25 is 17 workday(s)
from: 2015-02-03 to: 2015-02-26 is 18 workday(s)
from: 2015-02-03 to: 2015-02-27 is 19 workday(s)
from: 2015-02-03 to: 2015-02-28 is 19 workday(s)
from: 2015-02-04 to: 2015-02-22 is 13 workday(s)
from: 2015-02-04 to: 2015-02-23 is 14 workday(s)
from: 2015-02-04 to: 2015-02-24 is 15 workday(s)
from: 2015-02-04 to: 2015-02-25 is 16 workday(s)
from: 2015-02-04 to: 2015-02-26 is 17 workday(s)
from: 2015-02-04 to: 2015-02-27 is 18 workday(s)
from: 2015-02-04 to: 2015-02-28 is 18 workday(s)
from: 2015-02-05 to: 2015-02-22 is 12 workday(s)
from: 2015-02-05 to: 2015-02-23 is 13 workday(s)
from: 2015-02-05 to: 2015-02-24 is 14 workday(s)
from: 2015-02-05 to: 2015-02-25 is 15 workday(s)
from: 2015-02-05 to: 2015-02-26 is 16 workday(s)
from: 2015-02-05 to: 2015-02-27 is 17 workday(s)
from: 2015-02-05 to: 2015-02-28 is 17 workday(s)
from: 2015-02-06 to: 2015-02-22 is 11 workday(s)
from: 2015-02-06 to: 2015-02-23 is 12 workday(s)
from: 2015-02-06 to: 2015-02-24 is 13 workday(s)
from: 2015-02-06 to: 2015-02-25 is 14 workday(s)
from: 2015-02-06 to: 2015-02-26 is 15 workday(s)
from: 2015-02-06 to: 2015-02-27 is 16 workday(s)
from: 2015-02-06 to: 2015-02-28 is 16 workday(s)
from: 2015-02-07 to: 2015-02-22 is 10 workday(s)
from: 2015-02-07 to: 2015-02-23 is 11 workday(s)
from: 2015-02-07 to: 2015-02-24 is 12 workday(s)
from: 2015-02-07 to: 2015-02-25 is 13 workday(s)
from: 2015-02-07 to: 2015-02-26 is 14 workday(s)
from: 2015-02-07 to: 2015-02-27 is 15 workday(s)
from: 2015-02-07 to: 2015-02-28 is 15 workday(s)
```

I use a simple function to accomplish that. Maybe is not the most efficient but it works. It doesn't require Moment.js. it's just Javascript.

```
function getNumWorkDays(startDate, endDate) {
var numWorkDays = 0;
var currentDate = new Date(startDate);
while (currentDate <= endDate) {
// Skips Sunday and Saturday
if (currentDate.getDay() !== 0 && currentDate.getDay() !== 6) {
numWorkDays++;
}
currentDate = currentDate.addDays(1);
}
return numWorkDays;
}
```

To `addDays`

, I use the following function:

```
Date.prototype.addDays = function (days) {
var date = new Date(this.valueOf());
date.setDate(date.getDate() + days);
return date;
};
```

I've made an adaptation to Kokizzu answer, in order to fix a Summer Time problem. In Brazilian Timezone (GMT -3), the difference between 17/10/2017 and 18/10/2017 was -2.71 instead of 2.

The start of the week was 15/10/2017 00:00 UTC or 14/10/2017 21:00-03:00

The end of the week was 22/10/2017 00:00 UTC or 21/10/2017 22:00-02:00 (Summer Time)

Therefore, instead of 7, the difference between "first" and "last" variable in days was 6 (or 8, depending on your Timezone).

The code fixed is below:

```
start = moment(start).utc().add(start.utcOffset(), 'm'); // Ignore timezones
end = moment(end).utc().add(end.utcOffset(), 'm'); // Ignore timezones
var first = start.clone().endOf('week'); // end of first week
var last = end.clone().startOf('week'); // start of last week
// Fixing Summer Time problems
firstCorrection = moment(first).utc().add(60, 'm').toDate(); //
var days = last.diff(firstCorrection,'days') * 5 / 7; // this will always multiply of 7
var wfirst = first.day() - start.day(); // check first week
if(start.day() == 0) --wfirst; // -1 if start with sunday
var wlast = end.day() - last.day(); // check last week
if(end.day() == 6) --wlast; // -1 if end with saturday
return wfirst + days + wlast; // get the total (subtract holidays if needed)
```

I found kokizzu's answer didn't work if days were in the same week (e.g. sun to sat), so settled for this instead :

```
function calcBusinessDays(startDate, endDate) {
var day = moment(startDate);
var businessDays = 0;
while (day.isSameOrBefore(endDate,'day')) {
if (day.day()!=0 && day.day()!=6) businessDays++;
day.add(1,'d');
}
return businessDays;
}
```

By using momentjs, it's possible this way:

```
private calculateWorkdays(startDate: Date, endDate: Date): number {
// + 1 cause diff returns the difference between two moments, in this case the day itself should be included.
const totalDays: number = moment(endDate).diff(moment(startDate), 'days') + 1;
const dayOfWeek = moment(startDate).isoWeekday();
let totalWorkdays = 0;
for (let i = dayOfWeek; i < totalDays + dayOfWeek; i++) {
if (i % 7 !== 6 && i % 7 !== 0) {
totalWorkdays++;
}
}
return totalWorkdays;
}
```

you can try this(without loop):

```
function getBusinessDays(endDate, startDate) {
var lastDay = moment(endDate);
var firstDay = moment(startDate);
let calcBusinessDays = 1 + (lastDay.diff(firstDay, 'days') * 5 -
(firstDay.day() - lastDay.day()) * 2) / 7;
if (lastDay.day() == 6) calcBusinessDays--;//SAT
if (firstDay.day() == 0) calcBusinessDays--;//SUN
return calcBusinessDays;
}
```

I have been used a useful library *moment-business-days* coupled with *moment*

NPM Link of Moment-business-days

```
const diff = moment('05-15-2017', 'MM-DD-YYYY').businessDiff(moment('05-08-2017','MM-DD-YYYY'));
// diff = 5
```

©2020 All rights reserved.