Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

add/subtract business days in Javascript

I need a Date.prototype.addBusDays function that'll take an integer as the number of working days to add to the date.

However, there are two considerations: 1. Weekends, 2. Holidays (which I imagine would be a preset array to compare against. If beginning date and end date contain 3 holidays, then you push out the end date by 3)

I have come across some scripts online, one dilemma I can think of is, lets say you address all the weekends first, then you do the holidays, what if you +1 day (due to holiday), and your end date is pushed into a weekends again...<

Any ideas? Thanks!

EDIT:

This is a part of a scheduling tool I am developing, which mean the dates will be tied to tasks which are linked together. Adding 1 day to a task, will trigger a recalculation of everything tied to it, potentially all dates in the database.

like image 397
William Sham Avatar asked Jun 27 '11 23:06

William Sham


People also ask

How to add and subtract days in JavaScript?

You can use d. setDate(d. getDate() + days) with both positive and negative values for days to add and subtract days respectively.

How do you minus days from date in JS?

To subtract days to a JavaScript Date object, use the setDate() method. Under that, get the current days and subtract days. JavaScript date setDate() method sets the day of the month for a specified date according to local time.

Can you subtract dates in JavaScript?

To subtract days from a JavaScript Date object, you need to: Call the getDate() method to get the day of the Date object. Subtract the number of days you want from the getDate() returned value. Call the setDate() method to set the day of the Date object.

How add days to date in js?

The setDate() method can be used to add days to a date.


2 Answers

Datageek's solution helped me but I needed to augment it. This still doesn't do holidays but does do working days with the option of including Sat and/or Sun, and does support adding negative days:-

function AddWorkingDays(datStartDate, lngNumberOfWorkingDays, blnIncSat, blnIncSun) {
    var intWorkingDays = 5;
    var intNonWorkingDays = 2;
    var intStartDay = datStartDate.getDay(); // 0=Sunday ... 6=Saturday
    var intOffset;
    var intModifier = 0;

    if (blnIncSat) { intWorkingDays++; intNonWorkingDays--; }
    if (blnIncSun) { intWorkingDays++; intNonWorkingDays--; }
    var newDate = new Date(datStartDate)
    if (lngNumberOfWorkingDays >= 0) {
        // Moving Forward
        if (!blnIncSat && blnIncSun) {
            intOffset = intStartDay;
        } else {
            intOffset = intStartDay - 1;
        }
        // Special start Saturday rule for 5 day week
        if (intStartDay == 6 && !blnIncSat && !blnIncSun) {
            intOffset -= 6;
            intModifier = 1;
        }
    } else {
        // Moving Backward
        if (blnIncSat && !blnIncSun) {
            intOffset = intStartDay - 6;
        } else {
            intOffset = intStartDay - 5;
        }
        // Special start Sunday rule for 5 day week
        if (intStartDay == 0 && !blnIncSat && !blnIncSun) {
            intOffset++;
            intModifier = 1;
        }
    }
    // ~~ is used to achieve integer division for both positive and negative numbers
    newDate.setTime(datStartDate.getTime() + (new Number((~~((lngNumberOfWorkingDays + intOffset) / intWorkingDays) * intNonWorkingDays) + lngNumberOfWorkingDays + intModifier)*86400000));
    return newDate;
}
like image 190
EpochGrinder Avatar answered Sep 22 '22 11:09

EpochGrinder


Have a look at the following implementation. Sourced from about.com

addWeekdays = function(date, dd) {
  var wks = Math.floor(dd/5);
  var dys = dd.mod(5);
  var dy = this.getDay();
  if (dy === 6 && dys > -1) {
     if (dys === 0) {dys-=2; dy+=2;}
     dys++; dy -= 6;
  }
  if (dy === 0 && dys < 1) {
    if (dys === 0) {dys+=2; dy-=2;}
    dys--; dy += 6;
  }
  if (dy + dys > 5) dys += 2;
  if (dy + dys < 1) dys -= 2;
  date.setDate(date.getDate()+wks*7+dys);
}

var date = new Date();
addWeekdays(date, 9);
like image 37
Datageek Avatar answered Sep 18 '22 11:09

Datageek