Calculate Business Days in Month with Javascript - javascript

I'm trying to do 2 things.
Calculate number of business days to date in a given month based on current day (i.e. today is March 7, 2012 therefore, 5 business days have passed)
Calculate number of business days to go in a given month based on current day (i.e. Today is March 7, 2012 therefore, there are 17 business days left this month.
Any help here would be much appreciated.
EDIT:
This is what I've tried so far:
function isWeekday(year, month, day) {var day = new Date(year, month, day).getDay();return day !=0 && day !=6;}
function getWeekdaysInMonth(month, year) {var days = daysInMonth(month, year);var weekdays = 0;for(var i=0; i< days; i++) {if (isWeekday(year, month, i+1)) weekdays++;}return weekdays;}
function calcBusinessDays(dDate1, dDate2) {
var iWeeks, iDateDiff, iAdjust = 0;
if (dDate2 < dDate1) return -1; // error code if dates transposed
var iWeekday1 = dDate1.getDay(); // day of week
var iWeekday2 = dDate2.getDay();
iWeekday1 = (iWeekday1 == 0) ? 7 : iWeekday1; // change Sunday from 0 to 7
iWeekday2 = (iWeekday2 == 0) ? 7 : iWeekday2;
if ((iWeekday1 > 5) && (iWeekday2 > 5)) iAdjust = 1; // adjustment if both days on weekend
iWeekday1 = (iWeekday1 > 5) ? 5 : iWeekday1; // only count weekdays
iWeekday2 = (iWeekday2 > 5) ? 5 : iWeekday2;
// calculate differnece in weeks (1000mS * 60sec * 60min * 24hrs * 7 days = 604800000)
iWeeks = Math.floor((dDate2.getTime() - dDate1.getTime()) / 604800000)
if (iWeekday1 <= iWeekday2) {
iDateDiff = (iWeeks * 5) + (iWeekday2 - iWeekday1)
} else {
iDateDiff = ((iWeeks + 1) * 5) - (iWeekday1 - iWeekday2)
}
iDateDiff -= iAdjust // take into account both days on weekend
return (iDateDiff + 1); // add 1 because dates are inclusive
}
Not quite sure how to put it all together to get business days passed and business days to go.

Here's a really simple function that just loops over the days, should be fast enough as it should never have to loop more than 31 times. If the current day is a business day, it's counted in the days past:
function businessDays(date) {
// Copy date
var t = new Date(date);
// Remember the month number
var m = date.getMonth();
var d = date.getDate();
var daysPast = 0, daysToGo = 0;
var day;
// Count past days
while (t.getMonth() == m) {
day = t.getDay();
daysPast += (day == 0 || day == 6)? 0 : 1;
t.setDate(--d);
}
// Reset and count days to come
t = new Date(date);
t.setDate(t.getDate() + 1);
d = t.getDate();
while (t.getMonth() == m) {
day = t.getDay();
daysToGo += (day == 0 || day == 6)? 0 : 1;
t.setDate(++d);
}
return [daysPast, daysToGo];
}
alert(businessDays(new Date(2012,2,7))); // 7-Mar-2012 => 5, 17

Related

Return list of date between specific range selected from datepicker (include and exclude weekends)

I try to code with JavaScript and now, I have another problem. The intended goal is to calculate the number of days and to return list of those date between two selected dates from datepicker. The trick is: the system should provide two option: during all day of the week (including Saturday and Sunday) and only during working days. I tried to do this on my own, but I am stuck. I have also tried to find out if anyone happened to asked the same question, but the result is no. Here is my code. Can anyone help me with this? Thank you!
$("#calculate").click(function() {
// TO CALCULATE TOTAL DAYS
startdate.setHours(0, 0, 0, 1);
enddate.setHours(23, 59, 59, 999);
var days = Math.ceil(enddate - startdate) / (1000 * 60 * 60 * 24);
var weeks = Math.floor(days / 7);
days = days - (weeks * 2);
var month = startdate.getMonth();
var day = startdate.getDate();
var year = startdate.getFullYear();
// ONLY DURING WORKING DAYS
$("#weekday").change(function() {
if ($(this).is(':checked')) {
var startday = startdate.getDay();
var endday = enddate.getDay();
if (startday - endday > 1) {
days = days - 2
}
if (startday == 0 && endday != 6) {
days = days - 1
}
if (endday == 6 && startday != 0) {
days = days - 1
}
// TO SHOW THE LIST OF DATE BETWEEN START AND END DATE
while (startdate <= enddate) {
if (startday < 6 && startday > 0) {
month = startdate.getMonth() + 1
}
if (month <= 9) {
month = "0" + month
}
var day = startdate.getdate();
if (day <= 9) {
day = "0" + day
}
}
startdate.setDate(startdate.getDate() + 1);
}
})
})
var quantity = $("#quantity").val();
var delivery = Math.round(quantity / days);
var datearray = document.write(day + "." + month + "." + startdate.getFullYear());
if (enddate < startdate) {
alert("Start date must be earlier than end date!")
} else if (quantity == 0) {
alert("Quantity must be bigger than 0")
} else {
append("<br>Total " + days + " selected days<br/>");
append("<br>Shipment" + delivery + " pc(s) per day<br/>");
append("<br>During period of" + datearray + "<br/>")
}
});

How to calculate the total days between two selected calendar dates

Let say i have startDate = 7/16/2015 and endDate = 7/20/2015. This 2 dates are stored in a SharePoint list.
If user select the exact date with the date in SharePoint list, it can calculate the total days = 2 , which means that without calculate on the other days.
Anyone can please help on this?
I use the following code to calculate the total day of difference without counting on weekend. But I cant figure out the way how to calculate the total day of selected date without counting on other days.
function workingDaysBetweenDates(startDate,endDate) {
// Validate input
if (endDate < startDate)
return 'Invalid !';
// 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);
var days = days - (weeks * 2);
// Handle special cases
var startDay = startDate.getDay();
var endDay = endDate.getDay();
// Remove weekend not previously removed.
if (startDay - endDay > 1)
days = days - 2;
// Remove start day if span starts on Sunday but ends before Saturday
if (startDay == 0 && endDay != 6)
days = days - 1;
// Remove end day if span ends on Saturday but starts after Sunday
if (endDay == 6 && startDay != 0)
days = days - 1;
return days;
}
The following function calculates the number of business days between two dates
function getBusinessDatesCount(startDate, endDate) {
var count = 0;
var curDate = startDate;
while (curDate <= endDate) {
var dayOfWeek = curDate.getDay();
if(!((dayOfWeek == 6) || (dayOfWeek == 0)))
count++;
curDate.setDate(curDate.getDate() + 1);
}
return count;
}
//Usage
var startDate = new Date('7/16/2015');
var endDate = new Date('7/20/2015');
var numOfDates = getBusinessDatesCount(startDate,endDate);
$('div#result').text(numOfDates);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="result"/>
First you have to calculate the difference in time, then convert the time to days
var calculateDifference = function(date1, date2){
var timeDifference = Math.abs(date2.getTime() - date1.getTime());
return Math.ceil(timeDifference / (1000 * 3600 * 24));//ms * seconds * hours
}
var difference = calculateDifference(new Date("7/16/2015"), new Date("7/20/2015"));
untested, but should work...
Using moment startDate and endDate:
function getBusinessDaysCount(startDate, endDate) {
let relativeDaySequence = [...Array(endDate.diff(startDate, "days")).keys()];
let daySequence = relativeDaySequence.map(relativeDay => {
let startDateClone = startDate.clone();
return startDateClone.add(relativeDay, "days");
});
return daySequence.reduce(
(dayCount, currentDay) => dayCount + (currentDay.day() === 0 || currentDay.day() === 6 ? 0 : 1),
0
);
}
Can Try this it will also work.
//fromDate is start date and toDate is end Date
var timeDiff = Math.abs(toDate.getTime() - fromDate.getTime());
var diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24)) ;
// var startDay = fromDate.getDay();
debugger;
var diffDayWeek = diffDays + fromDate.getDay();
var diffDiv = Math.floor(parseInt(diffDayWeek/7));
diffDiv *= 2; "Saturday and Sunday are Weekend
diffDays += 1 - diffDiv;

How to check if days between two dates are weekdays?

I have form where user take two dates from calendar. I want to check if days between two dates that user selected are in from friday to monday (include).
I found script that count weekdays (days that are include satuday and sunday):
function calcBusinessDays (dDate1, dDate2) {
var iWeeks, iDateDiff, iAdjust = 0;
if (dDate2 < dDate1) return 0;
var iWeekday1 = dDate1.getDay();
var iWeekday2 = dDate2.getDay();
iWeekday1 = (iWeekday1 == 0) ? 7 : iWeekday1; // change Sunday from 0 to 7
iWeekday2 = (iWeekday2 == 0) ? 7 : iWeekday2;
if ((iWeekday1 > 5) && (iWeekday2 > 5)) iAdjust = 1; // adjustment if both days on weekend
iWeekday1 = (iWeekday1 > 5) ? 5 : iWeekday1; // only count weekdays
iWeekday2 = (iWeekday2 > 5) ? 5 : iWeekday2;
// calculate differnece in weeks (1000mS * 60sec * 60min * 24hrs * 7 days = 604800000)
iWeeks = Math.floor((dDate2.getTime() - dDate1.getTime()) / 604800000)
if (iWeekday1 <= iWeekday2) {
iDateDiff = (iWeeks * 5) + (iWeekday2 - iWeekday1)
} else {
iDateDiff = ((iWeeks + 1) * 5) - (iWeekday1 - iWeekday2)
}
iDateDiff -= iAdjust // take into account both days on weekend
return (iDateDiff + 1); // add 1 because dates are inclusive
}
how to modify it to include friday and monday?
Just put this together real quick but it should work.
I had trouble understanding your sample code. Just thought this might work a little better.
var calcBusinessDays = function (dDate1, dDate2) {
//We are working with time stamps
var from = dDate1.getTime()
, to = dDate2.getTime()
, tempDate = new Date()
, count = 0;
//loop through each day between the dates 86400000 = 1 day
for(var _from = from; _from < to; _from += 86400000){
//set the day
tempDate.setTime(_from);
//If it is a weekend add 1 to count
if ((tempDate.getDay() <= 1) || (tempDate.getDay() >= 5)) {
count++;
}
}
//return count =)
return count;
}
This will add 1 for Friday, Saturday, Sunday and Monday.
The only line that would need to be changed if you wanted other days would be the if statement nested in the for loop.

Counts days excluding weekdays and holidays

I know that this question is been asked a lot of time , but please help i am not able to find the solution
with the code below i am able to calculate no of days excluding weekdays
Now i want to also exclude public holidays says for eg 08/15/2012 , 09/12/2012 , 12/20/2012 , please help
function namet()
{
var iWeeks, iDateDiff, iAdjust = 0;
var nodays = document.getElementById("timestamp1").value;
var nodays1 = document.getElementById("timestamp").value;
var dDate1 = new Date(nodays1);
var dDate2 = new Date(nodays);
if (dDate2 < dDate1) {
alert("End Date : Enter date more than Start Date ");
}
// error code if dates transposed
var iWeekday1 = dDate1.getDay(); // day of week
var iWeekday2 = dDate2.getDay();
iWeekday1 = (iWeekday1 == 0) ? 7 : iWeekday1; // change Sunday from 0 to 7
iWeekday2 = (iWeekday2 == 0) ? 7 : iWeekday2;
if ((iWeekday1 > 5) && (iWeekday2 > 5)) iAdjust = 1; // adjustment if both days on weekend
iWeekday1 = (iWeekday1 > 5) ? 5 : iWeekday1; // only count weekdays
iWeekday2 = (iWeekday2 > 5) ? 5 : iWeekday2;
// calculate differnece in weeks (1000mS * 60sec * 60min * 24hrs * 7 days = 604800000)
iWeeks = Math.floor((dDate2.getTime() - dDate1.getTime()) / 604800000)
if (iWeekday1 <= iWeekday2) {
iDateDiff = (iWeeks * 5) + (iWeekday2 - iWeekday1)
} else {
iDateDiff = ((iWeeks + 1) * 5) - (iWeekday1 - iWeekday2)
}
iDateDiff -= iAdjust // take into account both days on weekend
var final = (iDateDiff + 1); // add 1 because dates are inclusive
document.leaveapplication.noofdays3.value = final;
You will need a list of holidays which fall on weekdays.
Calculate days between start and end
Calculate weekends between start and end (days modulo 7, then adjust for the positions in the final week)
Count all the holidays in your list between the dates and subtract that too.

Find day difference between two dates (excluding weekend days)

Hi i am using jquery-ui datepicker to select date and date.js to find difference between 2 dates.
Right now the problem is I want to exclude weekend days from calculation (saturday and sunday). How should i do that?
For example the user select start date (13/8/2010) and end date (16/8/2010). Since 14/8/2010 and 15/8/2010 is in week days, instead of 4 days total, i want it to be only 2 days.
This is the code im using right now:
<script type="text/javascript">
$("#startdate, #enddate").change(function() {
var d1 = $("#startdate").val();
var d2 = $("#enddate").val();
var minutes = 1000*60;
var hours = minutes*60;
var day = hours*24;
var startdate1 = getDateFromFormat(d1, "d-m-y");
var enddate1 = getDateFromFormat(d2, "d-m-y");
var days = 1 + Math.round((enddate1 - startdate1)/day);
if(days>0)
{ $("#noofdays").val(days);}
else
{ $("#noofdays").val(0);}
});
</script>
Maybe someone else can help you converting this function into JQuery's framework...
I found this function here.
function calcBusinessDays(dDate1, dDate2) { // input given as Date objects
var iWeeks, iDateDiff, iAdjust = 0;
if (dDate2 < dDate1) return -1; // error code if dates transposed
var iWeekday1 = dDate1.getDay(); // day of week
var iWeekday2 = dDate2.getDay();
iWeekday1 = (iWeekday1 == 0) ? 7 : iWeekday1; // change Sunday from 0 to 7
iWeekday2 = (iWeekday2 == 0) ? 7 : iWeekday2;
if ((iWeekday1 > 5) && (iWeekday2 > 5)) iAdjust = 1; // adjustment if both days on weekend
iWeekday1 = (iWeekday1 > 5) ? 5 : iWeekday1; // only count weekdays
iWeekday2 = (iWeekday2 > 5) ? 5 : iWeekday2;
// calculate differnece in weeks (1000mS * 60sec * 60min * 24hrs * 7 days = 604800000)
iWeeks = Math.floor((dDate2.getTime() - dDate1.getTime()) / 604800000)
if (iWeekday1 < iWeekday2) { //Equal to makes it reduce 5 days
iDateDiff = (iWeeks * 5) + (iWeekday2 - iWeekday1)
} else {
iDateDiff = ((iWeeks + 1) * 5) - (iWeekday1 - iWeekday2)
}
iDateDiff -= iAdjust // take into account both days on weekend
return (iDateDiff + 1); // add 1 because dates are inclusive
}
var date1 = new Date("August 11, 2010 11:13:00");
var date2 = new Date("August 16, 2010 11:13:00");
alert(calcBusinessDays(date1, date2));
## EDITED ##
If you want to use it with your that format just:
Your code will look like:
function calcBusinessDays(dDate1, dDate2) { // input given as Date objects
var iWeeks, iDateDiff, iAdjust = 0;
if (dDate2 < dDate1) return -1; // error code if dates transposed
var iWeekday1 = dDate1.getDay(); // day of week
var iWeekday2 = dDate2.getDay();
iWeekday1 = (iWeekday1 == 0) ? 7 : iWeekday1; // change Sunday from 0 to 7
iWeekday2 = (iWeekday2 == 0) ? 7 : iWeekday2;
if ((iWeekday1 > 5) && (iWeekday2 > 5)) iAdjust = 1; // adjustment if both days on weekend
iWeekday1 = (iWeekday1 > 5) ? 5 : iWeekday1; // only count weekdays
iWeekday2 = (iWeekday2 > 5) ? 5 : iWeekday2;
// calculate differnece in weeks (1000mS * 60sec * 60min * 24hrs * 7 days = 604800000)
iWeeks = Math.floor((dDate2.getTime() - dDate1.getTime()) / 604800000)
if (iWeekday1 < iWeekday2) { //Equal to makes it reduce 5 days
iDateDiff = (iWeeks * 5) + (iWeekday2 - iWeekday1)
} else {
iDateDiff = ((iWeeks + 1) * 5) - (iWeekday1 - iWeekday2)
}
iDateDiff -= iAdjust // take into account both days on weekend
return (iDateDiff + 1); // add 1 because dates are inclusive
}
$("#startdate, #enddate").change(function() {
var d1 = $("#startdate").val();
var d2 = $("#enddate").val();
var minutes = 1000 * 60;
var hours = minutes * 60;
var day = hours * 24;
var startdate1 = new Date(d1);
var enddate1 = new Date(d2);
var newstartdate = new Date();
newstartdate.setFullYear(startdate1.getYear(), startdate1.getMonth(), startdate1.getDay());
var newenddate = new Date();
newenddate.setFullYear(enddate1.getYear(), enddate1.getMonth(), enddate1.getDay());
var days = calcBusinessDays(newstartdate, newenddate);
if (days > 0) {
$("#noofdays").val(days);
} else {
$("#noofdays").val(0);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label>Start Date
<input type="date" id="startdate" value="2019-03-03"/>
</label>
<label>End Date
<input type="date" id="enddate" value="2019-03-06"/>
</label>
<label>N. of days
<output id="noofdays"/>
</label>
To do this, you should NOT search all days between these dates !
It's not complicated, look some evident assumptions:
All full-week has 7-days.
Which 2 are weekend-days.
And which 5 are business-day.
Evident conclusions:
Look all days is loss of time.
Check what day is weekend to all week is loss of time.
Without tedious explanation.. let me show the code:
function getBusinessDateCount (startDate, endDate) {
var elapsed, daysBeforeFirstSaturday, daysAfterLastSunday;
var ifThen = function (a, b, c) {
return a == b ? c : a;
};
elapsed = endDate - startDate;
elapsed /= 86400000;
daysBeforeFirstSunday = (7 - startDate.getDay()) % 7;
daysAfterLastSunday = endDate.getDay();
elapsed -= (daysBeforeFirstSunday + daysAfterLastSunday);
elapsed = (elapsed / 7) * 5;
elapsed += ifThen(daysBeforeFirstSunday - 1, -1, 0) + ifThen(daysAfterLastSunday, 6, 5);
return Math.ceil(elapsed);
}
function calc() {
let start = document.querySelector('#startDate').value,
end = document.querySelector('#endDate').value,
result = getBusinessDateCount(new Date(start), new Date(end));
document.querySelector('#result').value = result;
}
Start date: <input type="date" id="startDate" value="2020-01-04"><br>
End date: <input type="date" id="endDate" value="2020-01-06"><br>
<input type="button" onclick="calc()" value="Get business days"><br>
Business days: <input id="result" readonly>
You can test it yourself with any dates.
I just want to notice that this code ONLY consumed 0.43 sec between dates from 2000 to 2015... It is much more fast than some other codes.
Hope it helps...
Nice coding !!
This is how I would do it
function getDays(d1, d2) {
var one_day=1000*60*60*24;
var d1_days = parseInt(d1.getTime()/one_day) - 1;
var d2_days = parseInt(d2.getTime()/one_day);
var days = (d2_days - d1_days);
var weeks = (d2_days - d1_days) / 7;
var day1 = d1.getDay();
var day2 = d2.getDay();
if (day1 == 0) {
days--;
} else if (day1 == 6) {
days-=2;
}
if (day2 == 0) {
days-=2;
} else if (day2 == 6) {
days--;
}
days -= parseInt(weeks) * 2;
alert(days);
}
getDays(new Date("June 8, 2004"),new Date("February 6, 2010"));
EDIT
To clarify my comment to #keenebec...
That solution will work for small date differences quite nicely and is easy to understand. But take something as "short" as a 6 year span and you can see a remarkable difference in speed.
http://jsfiddle.net/aSvxv/
I included all 3 answers and the original answer is indeed the fastest, but not by much and the trade off for a few microseconds of execution is somewhat trivial to me in favor of readability.
Date.prototype.addDays = function(days) {
var date = new Date(this.valueOf())
date.setDate(date.getDate() + days);
return date;
}
function getBusinessDatesCount(startDate, endDate) {
var count = 0;
var curDate = startDate;
while (curDate <= endDate) {
var dayOfWeek = curDate.getDay();
var isWeekend = (dayOfWeek == 6) || (dayOfWeek == 0);
if(!isWeekend)
count++;
curDate = curDate.addDays(1);
}
return count;
}
//Usage
var startDate = new Date('7/16/2015');
var endDate = new Date('7/20/2015');
var numOfDays = getBusinessDatesCount(startDate,endDate);
jQuery('div#result').text(numOfDays);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="result"/>
That looks like too much work to me. I'd rather let the computer do the heavy lifting-
//
Date.bizdays= function(d1, d2){
var bd= 0, dd, incr=d1.getDate();
while(d1<d2){
d1.setDate(++incr);
dd= d1.getDay();
if(dd%6)++bd;
}
return bd;
}
//test
var day1= new Date(2010, 7, 11), day2= new Date(2010, 7, 31);
alert(Date.bizdays(day1, day2))
To understand way.,
Actual days = 14
weeks for Actual days = 14/7=2
Weekends per week=2
Total weekends=2*weeks for days
So apply this ,
$('#EndDate').on('change', function () {
var start = $('#StartDate').datepicker('getDate');
var end = $('#EndDate').datepicker('getDate');
if (start < end) {
var days = (end - start) / 1000 / 60 / 60 / 24;
var Weeks=Math.round(days)/7;
var totalWeekends=Math.round(Weeks)*2;
var puredays=Math.round(days)-totalWeekends;
$('#days').text(Math.round(puredays) + "Working Days");
}
else {
alert("");
}
Thank you !
Important: Most answers here don't actually work if the start date (or sometimes the end date) is a saturday or sunday. I took the accepted response and modified it so that this issue is resolved now:
var dateDiff;
if (dateTo < dateFrom) return -1; // error code if dates transposed
var dateFromDayOrig = dateFrom.getDay(); // day of week
var dateToDayOrig = dateTo.getDay();
var dateFromDay = (dateFromDayOrig == 0) ? 7 : dateFromDayOrig; // change Sunday from 0 to 7
var dateToDay = (dateToDayOrig == 0) ? 7 : dateToDayOrig;
dateFromDay = (dateFromDay > 5) ? 5 : dateFromDay; // only count weekdays
dateToDay = (dateToDay > 5) ? 5 : dateToDay;
// calculate differnece in weeks (1000mS * 60sec * 60min * 24hrs * 7 days = 604800000)
var weekDifference = Math.floor((dateTo.getTime() - dateFrom.getTime()) / 604800000);
if (dateFromDay <= dateToDay) {
dateDiff = (weekDifference * 5) + (dateToDay - dateFromDay);
} else {
dateDiff = ((weekDifference + 1) * 5) - (dateFromDay - dateToDay);
}
// fix: remove one day if it's saturday or sunday
if (dateFromDayOrig >= 6 || dateFromDayOrig == 0) {
dateDiff--;
}
return (dateDiff + 1); // add 1 because dates are inclusive
There seems to be few issues with the response that has been marked as solution.
The statement setFullYear() is returning incorrect value if I choose start date as 06/11/2015. So instead, the startDate1 and endDate1 can be directly passed to the function.
If the start date is Saturday or Sunday, still the code is counting it(iWeekday1) as 5 days
If the end date is Saturday or Sunday, still the code is counting it(iWeekday2) as 5 days. But these 5 days already get counted in the iweeks calculation.
So instead of
iWeekday1 = (iWeekday1 > 5) ? 5 : iWeekday1; // only count weekdays
iWeekday2 = (iWeekday2 > 5) ? 5 : iWeekday2;
it should be
iWeekday1 = (iWeekday1 > 5) ? 0 : iWeekday1; // only count weekdays
iWeekday2 = (iWeekday2 > 5) ? 0 : iWeekday2;
The last IF condition should be executed when start and end date day is same like both are on same day, the date could be different
if (iWeekday1 <= iWeekday2)
The condition that adjusts if both days are weekends can be removed
iDateDiff -= iAdjust
Lastly, the +1 should be done only if start and end date falls on weekdays. Currently, it is adding in both the cases.
return (iDateDiff + 1);//Add condition to apply only if both days are weekdays
--can't comment on that answer as I do not have that reputation :)
I get it work with this code. Note that the function is from date.js and businessday js (thanks to Garis Suero). Start Date 11-08-2010 End Date 16-08-2010 will result 4 days of leave.
<script type="text/javascript">
$("#startdate, #enddate").change(function() {
var d1 = $("#startdate").val();
var d2 = $("#enddate").val();
var minutes = 1000*60;
var hours = minutes*60;
var day = hours*24;
var startdate1 = getDateFromFormat(d1, "d-m-y");
var enddate1 = getDateFromFormat(d2, "d-m-y");
var days = calcBusinessDays(new Date(startdate1),new Date(enddate1));
if(days>0)
{ $("#noofdays").val(days);}
else
{ $("#noofdays").val(0);}
});
</script>
What I did
function calcbusinessdays()
{
for(var c=0,e=0,d=new Date($("#startdate").val()),a=(new Date($("#enddate").val())-d)/864E5;0<=a;a--)
{
var b=new Date(d);
b.setDate(b.getDate()+a);
1==Math.ceil(b.getDay()%6/6)?c++:e++
}
$("#noofdays").html(c)
};
c is weekdays, e is weekends
function addDays(date, days) {
var result = new Date(date);
result.setDate(result.getDate() + days);
return result;
}
var currentDate;
selectFlixbleDates = [];
var monToSatDateFilter=[];
currentDate=new Date(date);
while(currentDate){
console.log("currentDate"+currentDate);
if(new Date(currentDate).getDay()!=0){
selectFlixbleDates.push(currentDate)
}
if(selectFlixbleDates.length==$scope.numberOfDatePick)
{
break;
}
currentDate=addDays(currentDate,1);
}
for (var i = 0; i < selectFlixbleDates.length; i++) {
// console.log(between[i]);
monToSatDateFilter.push((selectFlixbleDates[i].getMonth() + 1) + '/' + selectFlixbleDates[i].getDate() + '/' + selectFlixbleDates[i].getFullYear());
}
var endDate=monToSatDateFilter.slice(-1).pop();
var space =monToSatDateFilter.join(', ');
var sdfs= document.getElementById("maxPicks").value =space;
$scope.$apply(function() {
$scope.orderEndDate=monToSatDateFilter.slice(-1).pop()
$scope.orderStartDate=monToSatDateFilter[0];
});
document.getElementById("startDateEndDate").innerHTML =$scope.orderStartDate+ ' TO ' +$scope.orderEndDate
}
I have used Angular framework and Moment.js library to implement the solution.
My solution covers all the cases.
this.daysInBetween = this.endMoment.diff(this.startMoment, 'days') + 1;
this.weeksInBetween = this.endMoment.diff(this.startMoment, 'weeks');
this.weekDays = this.daysInBetween - (this.weeksInBetween * 2);
if ( (this.startMoment.day() === 0 && this.endMoment.day() === 6) ||
(this.startMoment.day() > this.endMoment.day()) ) {
// IF ONE WEEKEND WAS MISSED
this.weekDays-=2;
} else if ( this.startMoment.day() <= this.endMoment.day() &&
( this.startMoment.day() === 0 || this.startMoment.day() === 6 ||
this.endMoment.day() === 0 || this.endMoment.day() === 6) ) {
// IF EITHER OF DAYS WAS A WEEKEND
this.weekDays--;
}
Live Demo:
Calculate number of weekdays
I am currently working on a blog to write about my approach to this
specific problem. I will post the link to the blog on the comment.
Important: Most answers here don't actually work if the start date (or sometimes the end date) is a saturday or sunday.
For example: if your start and end date are
Saturday to Sunday or vice versa
or Saturday to Saturday
or Sunday to Sunday
So, here is the modified answer from the accepted answer
function calculateBusinessDays(dDate1, dDate2) {
var iWeeks, iDateDiff, iAdjust = 0;
if (dDate2 < dDate1) {
return -1;
}
var iWeekday1 = dDate1.getDay();
var iWeekday2 = dDate2.getDay();
iWeekday1 = (iWeekday1 === 0) ? 7 : iWeekday1;
iWeekday2 = (iWeekday2 === 0) ? 7 : iWeekday2;
if (iWeekday1 > 5 && iWeekday2 <= 6) {
iWeekday1 = 0;
iAdjust = 1;
}
iWeekday2 = (iWeekday1 === 0 && iWeekday2 === 6) ? 0 : iWeekday2;
if ((iWeekday1 > 5) && (iWeekday2 > 5)) iAdjust = 1;
iWeekday1 = (iWeekday1 > 5) ? 5 : iWeekday1;
iWeekday2 = (iWeekday2 > 5) ? 5 : iWeekday2;
iWeeks = Math.floor((dDate2.getTime() - dDate1.getTime()) / 604800000);
if (iWeeks===0 && iWeekday1===0 && iWeekday2===0
&& (dDate2.getTime() !== dDate1.getTime()) ) {
iWeeks = 1;
}
if (iWeekday1 <= iWeekday2) {
iDateDiff = (iWeeks * 5) + (iWeekday2 - iWeekday1)
} else {
iDateDiff = ((iWeeks + 1) * 5) - (iWeekday1 - iWeekday2)
}
iDateDiff -= iAdjust
return (iDateDiff + 1);
}

Categories

Resources