5

I want to generate next working day using JavaScript.

This is my code as of now

var today = new Date();
    today.setDate(today.getDate());
    var tdd = today.getDate();
    var tmm = today.getMonth()+1;
    var tyyyy = today.getYear();

    var date = new Date();

    date.setDate(date.getDate()+3);

Problem is, on Fridays it returns Saturday's date whereas I want it to be Monday

Rubén
  • 34,714
  • 9
  • 70
  • 166
werlox
  • 53
  • 1
  • 1
  • 5
  • 4
    Look at the day (`today.getDay()`), if it's 5 (Friday) add 3, if it's 6 (Saturday) add 2, otherwise add 1. – RobG Aug 25 '16 at 06:17
  • Tack on an if statement that says if the `date`'s day of the week is Saturday, add two more days. Add another if statement to check for Sunday. – jedifans Aug 25 '16 at 06:18

5 Answers5

15

This will choose the next working day when a date is passed to it.

I suggest you normalise the date you pass, so you will not be surprised around summertime/wintertime change

Updated in 2023

const getNextWork = date => {
  let day = date.getDay(), add = 1;
  if (day === 6)           add = 2; else 
  if (day === 5)           add = 3;
  date.setDate(date.getDate() + add); // will correctly handle 31+1 > 32 > 1st next month
  return date;
};


// tests:
const dt = new Intl.DateTimeFormat("en-US", {
  weekday: "short",
  year: "numeric",
  month: "long",
  day: "numeric",
  timeZone: "UTC",
  timeZoneName: "short",
  hour: "numeric",
  minute: "numeric",
});
const aDay = 24 * 60 * 60 * 1000;
// 26th of March 2023 is daylight savings date in my country
let date = new Date(2023, 2, 24, 15, 0, 0, 0).getTime();

for (let i = 0; i < 7; i++) {
  const d = new Date(date + i * aDay);
  console.log(dt.format(d), "-->", dt.format(getNextWork(d)));
}

Older code:

var today = new Date(2016, 7, 26,12,0,0,0,0); // Friday at noon
console.log("today, Monday",today,"day #"+today.getDay());
var next = new Date(today.getTime());
next.setDate(next.getDate()+1); // tomorrow
while (next.getDay() == 6 || next.getDay() == 0) next.setDate(next.getDate() + 1);
console.log("no change    ",next,"day #"+next.getDay());
console.log("-------");
// or without a loop:

function getNextWork(d) {
  d.setDate(d.getDate()+1); // tomorrow
  if (d.getDay()==0) d.setDate(d.getDate()+1);
  else if (d.getDay()==6) d.setDate(d.getDate()+2);
  return d;
}
next = getNextWork(today); // Friday
console.log("today, Friday",today);
console.log("next, Monday ",next);
console.log("-------");
today = new Date(2016, 7, 29,12,0,0,0); // Monday at noon
next = getNextWork(today);              // Still Monday at noon
console.log("today, Monday",today);
console.log("no change    ",next);
console.log("-------");

// Implementing Rob's comment

function getNextWork1(d) {
  var day = d.getDay(),add=1;
  if (day===5) add=3;
  else if (day===6) add=2;
  d.setDate(d.getDate()+add);  
  return d;
}
today = new Date(2016, 7, 26,12,0,0,0,0); // Friday at noon
next = getNextWork1(today);               // Friday
console.log("today, Friday",today);
console.log("next, Monday ",next);
console.log("-------");
today = new Date(2016, 7, 26,12,0,0,0,0); // Monday at noon
next = getNextWork1(today); // Monday
console.log("today, Monday",today);
console.log("no change    ",next);
mplungjan
  • 169,008
  • 28
  • 173
  • 236
4

You can add 1 day at at time until you get to a day that isn't Saturday or Sunday:

function getNextBusinessDay(date) {
  // Copy date so don't affect original
  date = new Date(+date);
  // Add days until get not Sat or Sun
  do {
    date.setDate(date.getDate() + 1);
  } while (!(date.getDay() % 6))
  return date;
}

// today,    Friday 26 Aug 2016
[new Date(), new Date(2016,7,26)].forEach(function(d) {
  console.log(d.toLocaleString() + ' : ' + getNextBusinessDay(d).toLocaleString());
});

You can also test the day and add extra to get over the weekend:

// Classic Mon to Fri
function getNextWorkDay(date) {
  let d = new Date(+date);
  let day = d.getDay() || 7;
  d.setDate(d.getDate() + (day > 4? 8 - day : 1));
  return d;
}

for (let i=0, d=new Date(); i<7; i++) {
  console.log(`${d.toDateString()} -> ${getNextWorkDay(d).toDateString()}`);
  d.setDate(d.getDate() + 1);
}

Here is another approach where the work week can be specified using ECMAScript weekday numbers (Sun = 0, Mon = 1, etc.). Dates outside the range are shifted to the start of the next work week.

This is useful where the week is not the classic Mon to Fri, such as the Middle East where Sat to Wed is common or for some who might work Fri to Mon (or whatever).

function getNext(start, end, date) {
  let d = new Date(+date);
  d.setDate(d.getDate() + 1);
  let day = d.getDay();

  // Adjust end and day if necessary
  // The order of tests and adjustment is important
  if (end < start) {
    if (day <= end) {
      day += 7;
    }
    end += 7;
  }

  // If day is before start, shift to start
  if (day < start) {
    d.setDate(d.getDate() + start - day);

    // If day is after end, shift to next start (treat Sunday as 7)
  } else if (day > end) {
    d.setDate(d.getDate() + 8 - (day || 7));
  }
  return d;
}

// Examples
let f = new Intl.DateTimeFormat('en-GB', {
  weekday:'short',day:'2-digit', month:'short'});
let d = new Date();

[{c:'Work days Mon to Fri',s:1,e:5},
 {c:'Work days Sat to Wed',s:6,e:3},
 {c:'Work days Fri to Mon',s:5,e:1}
].forEach(({c,s,e}) => {
  for (let i = 0; i < 7; i++) {
    !i? console.log(`\n${c}`) : null;
    console.log(`${f.format(d)} => ${f.format(getNext(s, e, d))}`);
    d.setDate(d.getDate() + 1);
  }
});
RobG
  • 142,382
  • 31
  • 172
  • 209
0

Check this out: https://jsfiddle.net/e9a4066r/

function get_next_weekday (date) {
    var tomorrow = new Date(date.setDate(date.getDate() + 1))
    return tomorrow.getDay() % 6
        ? tomorrow
        : get_next_weekday(tomorrow)
}
Martin Gottweis
  • 2,721
  • 13
  • 27
  • 1
    This is a beautiful way to do it! Code just has some issues. One example: If we use Dec 31, 2016 date jumps to Feb 02 instead of Jan 02, 2017 - Need to handle boundaries for months and years. – Jersey_Guy Oct 03 '17 at 19:37
  • This is really just using recursion to iterate over weekends as for one of the other answers and it modifies the input Date. Recursion is typically less efficient than sequential processing. – RobG Sep 06 '21 at 15:34
0

The accepted answer will skip one day at a time, which answers the OPs question, but for anyone looking to add a variable number of days while still skipping weekends the function below may be helpful:

function addWorkDays(date, days) {   
  while (days > 0) {
    date.setDate(date.getDate() + 1);
    if (date.getDay() != 0 && date.getDay() != 6) {
      days -= 1;
    }
  }          
  return date;
}
Matt Rowles
  • 7,721
  • 18
  • 55
  • 88
William Stevens
  • 514
  • 6
  • 9
0

Thought I'd throw my hat in the ring here with:

function getNextBusinessDate(date) {
  // Create date array [S, M, T, W, T, F, S]
  const days = new Array(7);
  let nextDate = date;
  for(let i = 0; i < 7; i++) {
    days[nextDate.getDay()] = new Date(nextDate);
    nextDate.setDate(nextDate.getDate() + 1);
  }

  // Shift indices to index as though array was [M, T, W, T, F, S, S]
  // Then truncate with min to make F, S, S all yield M for next date
  return days[Math.min((date.getDay() + 6) % 7 + 1, 5) % 5 + 1];
}