Reputation: 63
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
Upvotes: 6
Views: 13782
Reputation: 11
Attempting in two lines:
do date.setDate(date.getDate() + 1);
while ([0, 6].includes(date.getDay()));
Upvotes: 1
Reputation: 177685
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
// update and return passed date object to next working day
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)));
}
If you do not want to update the passed date object have this instead
// find next working day and return a new date for that date
const getNewNextWork = date => {
const dateCopy = new Date(date);
let day = dateCopy.getDay(), add = 1;
if (day === 6) add = 2; else
if (day === 5) add = 3;
dateCopy.setDate(dateCopy.getDate() + add); // Modifying the copy, not the original date
return dateCopy;
};
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);
Upvotes: 17
Reputation: 1
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];
}
Upvotes: 0
Reputation: 147343
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);
}
});
Upvotes: 5
Reputation: 552
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;
}
Upvotes: 0
Reputation: 2739
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)
}
Upvotes: 0