如何在Javascript中计算两个日期之间的工作日。
说
Date 1 : 04-25-2013
Date 2 : 05-10-2013
Holidays : ["04-27-2013","05-03-2013"]
我希望在这两个日期之间存在除节假日之外的总天数,如果有,则不包括星期日。
我已经尝试了但是我无法为假期数组做到这一点。
答案 0 :(得分: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 。
获取两个日期之间的天数(星期日除外)的另一种方法是
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
这样可以节省每天的循环时间。在此之后,您将使用与上述相同的检查来删除假期(请记住将i
重新设置为holiday.length
)。
答案 1 :(得分: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++;
}
答案 2 :(得分: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
*/
答案 3 :(得分: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);