1

How to Calculate business days between two dates in Javascript.

Say

Date 1 : 04-25-2013
Date 2 : 05-10-2013

Holidays : ["04-27-2013","05-03-2013"]

I want total number of days excluding holidays if any exists between these two dates and excluding sundays if any.

I have tried but I can't be able to do it for holidays array.

4

4 回答 4

4

您需要做的是检查一天是否在您的开始和结束日期之间,如果为true则减去一天。然后,当您从一个日期到另一个日期时,您需要为每一天0星期日)添加一天。

此答案使用UTC时间,因此不必担心夏令时/时区等。

//                    yyyy-MM-dd hh:mm:ss
var start = new Date('2013-04-25T00:00:00Z'),
    end   = new Date('2013-05-10T00:00:00Z'),
    holiday = [
        new Date('2013-04-27T00:00:00Z'),
        new Date('2013-05-03T00:00:00Z')
    ], i = holiday.length,
    n_days = 0;
while (i--) { // loop over holidays
    if (holiday[i] >= start)
        if (holiday[i] <= end)
            n_days = n_days - 1; // day holiday within dates
}
while (start <= end) {
    if (start.getUTCDay()) n_days = n_days + 1; // not sunday
    start.setUTCHours(24); // add a day
}
console.log(n_days); // 12

我没有检查这是否在一天前结束。您可以通过使用每个来减少内存占用.valueOf(),除非start我们使用实际的Date方法。此外,您可能还想检查假期是否不是Sunday


获取两个日期之间的天数(不包括Sundays)的另一种方法是

n_days = (end - start) / 86400000; // time difference in days
i = n_days - start.getUTCDay(); // trim to first Sunday
i = i - i % 7; // trim to last Sunday
n_days = n_days - i / 7; // subtract Sundays

这样可以省去每天循环的麻烦。在此之后,您将使用与上述相同的检查来删除假期(请记住重新设置iholiday.length)。

于 2013-04-25T13:04:44.960 回答
1
diff=endDate-startDate;
var holidays=new Array("04-28-2013","05-22-2013","06-28-2013");
idx_holidays=0;
num_holidays=0;
while(idx_holidays < holidays.length)
   {
       holiday=new Date(holidays[idx_holidays]);
       if(diff>holiday-startDate)
           num_holidays++;
       idx_holidays++;
   }
于 2013-04-25T12:51:29.473 回答
0

/* 有多种方法可以做到这一点。

您可以将假期和周末的日期放在一个数组中。

通过过滤数组,您可以从

两个日期之间的实际天数,

或在您将工作日添加到开始日期时考虑它们。

当您跨越多年时,它会变得更加复杂

具有不同的假期数组,但这就是计算机的用途... */

if(!Array.prototype.filter){
    Array.prototype.filter= function(fun, scope){
        var T= this, A= [], i= 0, itm, L= T.length;
        if(typeof fun== 'function'){
            while(i<L){
                if(i in T){
                    itm= T[i];
                    if(fun.call(scope, itm, i, T)) A[A.length]= itm;
                }
                ++i;
            }
        }
        return A;
    }
}
Date.prototype.dayOfYear= function(){
    var j1= new Date(this);
    j1.setMonth(0,0);
    return  Math.round((this-j1)/8.64e7);
}

// this covers a few years of federal holidays:

var holidates={
    y2012:[1, 2, 16, 51, 149, 186, 247, 282, 316, 317, 327, 360],
    y2013:[1, 21, 49, 147, 185, 245, 287, 315, 332, 359],
    y2014:[1, 20, 48, 146, 185, 244, 286, 315, 331, 359],
    y2015:[1, 19, 47, 145, 184, 185, 250, 285, 315, 330, 359],
    y2016:[1, 18, 46, 151, 186, 249, 284, 316, 329, 360, 361],
    y2017:[1, 2, 16, 20, 51, 149, 185, 247, 282, 314, 315, 327, 359],
    y2018:[1, 15, 50, 148, 185, 246, 281, 315, 316, 326, 359],
    y2019:[1, 21, 49, 147, 185, 245, 287, 315, 332, 359],
    y2020:[1, 20, 48, 146, 185, 186, 251, 286, 316, 331, 360],
    y2021:[1, 18, 20, 46, 151, 185, 186, 249, 284, 315, 329, 358, 359],
    y2022:[1, 17, 52, 150, 185, 248, 283, 315, 328, 359, 360, 365],
    y2023:[1, 2, 16, 51, 149, 185, 247, 282, 314, 315, 327, 359]
}

// return an array of weekends and holidays for a given year, 
// or the current year. Each element is the day of the year,
// Jan 1 is 1.

function getOffdays(y){
    if(typeof y!= 'number') y= new Date().getFullYear();
    var offdays= [], i= 0, firstwk, lastwk, H= holidates['y'+y].slice(0);
    var d= 1, year= new Date(y, 0, 1);
    while(year.getDay()!= 0) year.setDate(++d);
    firstwk= year.dayOfYear();
    year.setMonth(11, 31);
    d= 31;
    if(year.getDay()== 6) lastwk= year.dayOfYear();
    else{
        while(year.getDay()!= 0) year.setDate(--d);
        lastwk= year.dayOfYear();
    }
    while(firstwk<= lastwk){
        offdays.push(firstwk-1, firstwk);
        firstwk+= 7;
    }
    if(offdays[0]== 0) offdays.shift();
    if(H) offdays= offdays.concat(H);
    return offdays.sort(function(a, b){
        return a-b;
    });
}

// expects two dates, 
// returns the number of business days between them

function bizDays(day1, day2){
    var dayfrom= day1, dayto= day2;
    if(day1>day2){
        dayto= day1;
        dayfrom= day2;
    }
    var offdays= 0, diff= Math.round((dayto-dayfrom)/8.64e7),
    d1= dayfrom.dayOfYear(), d2= dayto.dayOfYear(),
    y1= dayfrom.getFullYear(), y2= dayto.getFullYear();

    if(y1<y2){
        offdays= getOffdays(y1).filter(function(d){
            return d>= d1;
        }).length;
        while(y1+1<y2){
            offdays+= getOffdays(++y1).length;
        }
        offdays+= getOffdays(y1).filter(function(d){
            return d<= d2;
        }).length;
    }
    else{
        offdays= getOffdays(y1).filter(function(d){
            return d>= d1 && d<= d2;
        }).length;
    }
    return diff-offdays;
}

// expects an integer and an optional start date-
// uses the current date if no date is specified.
// returns the date that is biz business days after day1

function bizDaysAfter(biz, day1){
    var start= day1 || new Date(),
    end= new Date(day1), bdiff;

    end.setDate(start.getDate()+biz);
    bdiff= biz-bizDays(start, end);

    while(bdiff>0){
        end.setDate(end.getDate()+bdiff);
        bdiff= biz-bizDays(start, end);
    }
    return end;
}

//Some testing:

var D1= new Date(2013, 3, 25), D2= new Date(2013, 4, 15), 
days=14,
s1=D1.toLocaleDateString(), s2=D2.toLocaleDateString();

['Business days between '+ s1+' and\n'+s2+': '+bizDays(D1,D2)+' days.',
days+' business days after '+s1+':\n'+
bizDaysAfter(days,D1).toLocaleDateString()].join('\n\n');

/*  returned value: (String)
Business days between Thursday, April 25, 2013 and
Wednesday, May 15, 2013: 14 days.

14 business days after Thursday, April 25, 2013:
Wednesday, May 15, 2013
*/
于 2013-04-25T17:45:24.923 回答
0
//days count
var days_count = 0;

//start date 
var start = new Date("10/01/2017");

//end date
var end = new Date("10/21/2017");

//holidays array
var date_array = [ new Date('2017-01-26'), new Date('2017-03-13'), new 
Date('2017-03-29'), new Date('2017-08-15'), new Date('2017-08-25'), new 
Date('2017-10-02'), new Date('2017-10-19'), new Date('2017-12-25')];

while(start <= end){
    // 0 = Sunday and 6 = Saturday 
    if(start.getDay() > 0 && start.getDay() < 6){
        days_count = days_count + 1;
        for(var dat in date_array){
        var a = date_array[dat];
        a.setHours(0,0,0,0);
            if(a.getTime() == start.getTime()){
                days_count = days_count - 1;
            }
        }
    }
    var newDate = start.setDate(start.getDate() + 1);
    start = new Date(newDate);
}
console.log(days_count);
于 2017-10-16T06:41:15.337 回答