Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get next day, skip weekends

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

like image 662
werlox Avatar asked Dec 07 '22 21:12

werlox


2 Answers

This will choose the next working day.

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);
like image 124
mplungjan Avatar answered Dec 10 '22 11:12

mplungjan


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);
  }
});
like image 40
RobG Avatar answered Dec 10 '22 13:12

RobG