Compare Date range with moment.js - javascript

I am trying to get the following output:
Here is my code:
const start = "12/7/2018";
const end = "10/6/2019";
var startLease = moment(start, "MM/DD/YYYY");
var endLease = moment(end, "MM/DD/YYYY");
var array = [];
var i = 0;
var nextEnd;
while (1 == 1) {
var nextStart = nextEnd ? (nextEnd.date() > 28 ? nextEnd : nextEnd) : nextEnd || startLease.clone().add(i, 'M');
nextEnd = startLease.clone().add(i + 1, 'M') > endLease ? endLease : startLease.clone().add(i + 1, 'M');
if (nextEnd.date() > 28) {
nextEnd.subtract(1, 'days')
} else {}
array.push(nextEnd.diff(nextStart, 'days'));
if (nextEnd >= endLease) {
break;
} else {}
i += 1
}
console.log(array);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
Issue:
Instead of going from 7th-6th, it goes from 7th-7th of every month. I tried .subtract(1, 'days') but that doesn't output the correct values. However, this works for end of the month.
Any help is appreciated. Thank you.

I added some logging to your loop and cut it off after one iteration.
Only the first month is wrong for your example, so the issue is your expectation that if you add 1 month to December 7, 2018, you'll get January 6, 2019 (you'll actually get January 7, 2019).
I'm not sure what the condition that leads to subtracting a day is supposed to do. nextEnd.date() will resolve to the day of the month, which is always less than 28 for your example.
const start = "12/7/2018";
const end = "10/6/2019";
var startLease = moment(start, "MM/DD/YYYY");
var endLease = moment(end, "MM/DD/YYYY");
var array = [];
var i = 0;
var nextEnd;
while (1 == 1) {
var nextStart = nextEnd ? (nextEnd.date() > 28 ? nextEnd : nextEnd) : nextEnd || startLease.clone().add(i, 'M');
console.log(nextStart);
nextEnd = startLease.clone().add(i + 1, 'M') > endLease ? endLease : startLease.clone().add(i + 1, 'M');
console.log(nextEnd);
if (nextEnd.date() > 28) {
nextEnd.subtract(1, 'days')
} else {}
array.push(nextEnd.diff(nextStart, 'days'));
if (nextEnd >= endLease) {
break;
} else {}
i += 1;
break;
}
console.log(array);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>

This worked for me:
while(1==1){
var nextStart = nextEnd ? nextEnd : startLease.clone().add(i, 'M');
var tempstart = startLease.clone();
tempstart.date(1);
if (startLease.date() < endLease.date() && array.length == 0) {
i = -1;
}
tempstart.add(i + 1, 'M');
var days = [31, 28, 31, 30, 31, 30 ,31, 31, 30, 31, 30, 31];
var year = tempstart.year();
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
days[1] = 29;
if (endLease.date() > days[tempstart.month()]) {
tempstart.date(days[tempstart.month()]);
} else {
tempstart.date(endLease.date());
}
nextEnd = tempstart > endLease ? endLease : tempstart;
var diff_sum = nextEnd.diff(nextStart, 'days');
array.push (diff_sum);
if (nextEnd >= endLease) {
break;
}
i += 1
}

Related

issue with getting special day [duplicate]

I have an date, i need to add no. of days to get future date but weekends should be excluded.
i.e
input date = "9-DEC-2011";
No. of days to add = '13';
next date should be "28-Dec-2011"
Here weekends(sat/sun) are not counted.
Try this
var startDate = "9-DEC-2011";
startDate = new Date(startDate.replace(/-/g, "/"));
var endDate = "", noOfDaysToAdd = 13, count = 0;
while(count < noOfDaysToAdd){
endDate = new Date(startDate.setDate(startDate.getDate() + 1));
if(endDate.getDay() != 0 && endDate.getDay() != 6){
//Date.getDay() gives weekday starting from 0(Sunday) to 6(Saturday)
count++;
}
}
alert(endDate);//You can format this date as per your requirement
Working Demo
#ShankarSangoli
Here's a newer version which avoid recreating a Date object on each loop, note that it's wrapped in a function now.
function calcWorkingDays(fromDate, days) {
var count = 0;
while (count < days) {
fromDate.setDate(fromDate.getDate() + 1);
if (fromDate.getDay() != 0 && fromDate.getDay() != 6) // Skip weekends
count++;
}
return fromDate;
}
alert(calcWorkingDays(new Date("9/DEC/2011"), 13));
Here is an elegant solution without any looping or external library:
function addBusinessDaysToDate(date, days) {
var day = date.getDay();
date = new Date(date.getTime());
date.setDate(date.getDate() + days + (day === 6 ? 2 : +!day) + (Math.floor((days - 1 + (day % 6 || 1)) / 5) * 2));
return date;
}
var date = "9-DEC-2011";
var newDate = addBusinessDaysToDate(new Date(date.replace(/-/g, "/")), 13);
console.log(newDate.toString().replace(/\S+\s(\S+)\s(\d+)\s(\d+)\s.*/, '$2-$1-$3')); // alerts "28-Dec-2011"
or you can be like this
function addWeekdays(date, weekdays) {
var newDate = new Date(date.getTime());
var i = 0;
while (i < weekdays) {
newDate.setDate(newDate.getDate() + 1);
var day = newDate.getDay();
if (day > 1 && day < 7) {
i++;
}
}
return newDate;
}
var currentDate = new Date('10/31/2014');
var targetDate = addWeekdays(currentDate, 45);
alert(targetDate);
Using moment.js:
const DATE_FORMAT = 'D-MMM-YYYY';
const SUNDAY = 0; // moment day index
const SATURDAY = 6; // moment day index
const WEEKENDS = [SATURDAY, SUNDAY];
function addBusinessDays(stringDate, numberOfDays, dateFormat = DATE_FORMAT) {
const date = moment(stringDate, dateFormat);
let count = 0;
while (count < numberOfDays) {
date.add(1, 'day');
// Skip weekends
if (WEEKENDS.includes(date.day())) {
continue;
}
// Increment count
count++;
}
return date.format(dateFormat);
}
// Test cases
console.log(addBusinessDays('3-Mar-2021', 1)); // 4-Mar-2021
console.log(addBusinessDays('3-Mar-2021', 2)); // 5-Mar-2021
console.log(addBusinessDays('3-Mar-2021', 3)); // 8-Mar-2021
console.log(addBusinessDays('3-Mar-2021', 4)); // 9-Mar-2021
console.log(addBusinessDays('3-Mar-2021', 5)); // 10-Mar-2021
console.log(addBusinessDays('9-Dec-2011', 13)); // 28-Dec-2011
console.log(addBusinessDays('10-Dec-2011', 13)); // 28-Dec-2011 (Saturday, so remain on Friday)
console.log(addBusinessDays('11-Dec-2011', 13)); // 28-Dec-2011 (Sunday, so remain on Friday)
console.log(addBusinessDays('12-Dec-2011', 13)); // 29-Dec-2011
console.log(addBusinessDays('13-Dec-2011', 13)); // 30-Dec-2011
console.log(addBusinessDays('14-Dec-2011', 13)); // 2-Jan-2012
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
This question is quite old, but all the previous answers are iterating over the days one by one. That could be inefficient for a large number of days. This works for me, assuming days is a positive int and the startDate is a working day:
function addWorkingDates(startDate, days) {
const current_day = startDate.getDay() - 1; // Week day, starting on Monday
const weekend_days = 2 * parseInt((current_day + days) / 5);
startDate.setDate(changed_to.getDate() + days + weekend_days);
}
addWorkingDates(new Date(),5)
For some reason it was more intuitive to me to try this recursively. This version doesn't account for holidays, but you could change the isValid function to check whatever.
function addWeekdaysToDate(date, numberToAdd) {
var isValid = function(d) { return d.getDay() !== 0 && d.getDay() !== 6 }
if(Math.abs(numberToAdd) > 1) {
return addWeekdaysToDate(
addWeekdaysToDate(date, Math.sign(numberToAdd)),
numberToAdd - Math.sign(numberToAdd)
)
} else if(Math.abs(numberToAdd) === 1) {
var result = new Date(date)
result.setDate(result.getDate() + Math.sign(numberToAdd))
if(isValid(result)) {
return result
} else {
return addWeekdaysToDate(result, Math.sign(numberToAdd))
}
} else if(numberToAdd === 0) {
return date
}
return false
}
console.log(addWeekdaysToDate(new Date(), 1))
console.log(addWeekdaysToDate(new Date(), 5))
console.log(addWeekdaysToDate(new Date(), -7))
In certain browsers you may need a polyfill for Math.sign:
Math.sign = Math.sign || function(x) {
x = +x; // convert to a number
if (x === 0 || isNaN(x)) {
return Number(x);
}
return x > 0 ? 1 : -1;
}
try this solution
<script language="javascript">
function getDateExcludeWeekends(startDay, startMonth, startYear, daysToAdd) {
var sdate = new Date();
var edate = new Date();
var dayMilliseconds = 1000 * 60 * 60 * 24;
sdate.setFullYear(startYear,startMonth,startDay);
edate.setFullYear(startYear,startMonth,startDay+daysToAdd);
var weekendDays = 0;
while (sdate <= edate) {
var day = sdate.getDay()
if (day == 0 || day == 6) {
weekendDays++;
}
sdate = new Date(+sdate + dayMilliseconds);
}
sdate.setFullYear(startYear,startMonth,startDay + weekendDays+daysToAdd);
return sdate;
}
</script>
If you want to get the next working day, from a specific date, use the following code...
function getNextWorkingDay(originalDate) {
var nextWorkingDayFound = false;
var nextWorkingDate = new Date();
var dateCounter = 1;
while (!nextWorkingDayFound) {
nextWorkingDate.setDate(originalDate.getDate() + dateCounter);
dateCounter++;
if (!isDateOnWeekend(nextWorkingDate)) {
nextWorkingDayFound = true;
}
}
return nextWorkingDate;
}
function isDateOnWeekend(date) {
if (date.getDay() === 6 || date.getDay() === 0)
return true;
else
return false;
}
Try this
function calculate() {
var noOfDaysToAdd = 13;
var startDate = "9-DEC-2011";
startDate = new Date(startDate.replace(/-/g, "/"));
var endDate = "";
count = 0;
while (count < noOfDaysToAdd) {
endDate = new Date(startDate.setDate(startDate.getDate() + 1));
if (endDate.getDay() != 0 && endDate.getDay() != 6) {
count++;
}
}
document.getElementById("result").innerHTML = endDate;
}
<div>
Date of book delivery: <span id="result"></span><br /><br />
<input type="button" onclick="calculate();" value="Calculate" />
<br>
<br>
</div>

Get week days and specific time of day

I'm using javaScript to display an element on week days and in busines hours (Monday to Friday between 08:00 and 16:50).
I'm using this code:
var date = new Date();
var thisMin = date.getMinutes();
var thisHour = date.getHours();
var thisWeekday = date.getDay();
// True if Mon - Fri between 08:00 - 16:50
if (thisWeekday > 0 && thisWeekday < 6 && thisHour > 7 && (thisHour < 17 && thisMin <= 50)) {
alert("True");
} else {
alert("False");
}
- but is this the best way to code it? It seems like a lot of conditions and it's working all the time... Can it be done in a better way with javaScript?
Fiddle here.
Thanks.
Note that you have a condition with two distinct parts "must be within week interval" and "must be within time interval". The code can reflect this more clearly by being explicit.
For the time comparison I would reshape the current time so that you can use Date's <= and >= operators instead of reimplementing time comparisons yourself:
var startTime = new Date(0, 0, 0, 8, 0);
var endTime = new Date(0, 0, 0, 16, 50);
var startWeekday = 1;
var endWeekday = 5;
function shouldDisplay() {
var d = new Date();
function withinWeekInterval() {
return (d.getDay() >= startWeekday &&
d.getDay() <= endWeekday);
}
function withinTimeInterval() {
var now = new Date(0, 0, 0, d.getHours(), d.getMinutes());
return (now >= startTime &&
now <= endTime);
}
return (withinWeekInterval() && withinTimeInterval());
}
Manual test:
alert(shouldDisplay());
Try below Code :
var date = new Date();
var thisMin = date.getMinutes();
var thisHour = date.getHours();
var thisWeekday = date.getDay();
var isSuccess = false;
// True if Mon - Fri between 08:00 - 16:50
if (thisWeekday > 0 && thisWeekday < 6 && thisHour > 7 && (thisHour < 17)) {
if (thisHour == 16 && thisMin > 50) {
isSuccess = false;
} else {
isSuccess = true;
}
} else {
isSuccess = false;
}
alert(isSuccess);

First Tuesday of every Month

Hello I am trying to use the following code which is a mish mash of "lifted code" but it keeps pumping out todays date and time.
I am trying to get the date for the first Tuesday of every month at 19:00.
I am using W3C School Try-it for testing purposes.
<!DOCTYPE html>
<html>
<head>
<script>
function displayDate()
{
var myDate = new Date();
myDate.setHours(19, 00, 0, 0);
myDate.setYear(2013);
myDate.setDate(1);
myDate.setMonth();
//Find Tuesday
var tue = 2;
while(myDate.getDay() != tue) {
myDate.setDate(myDate.getDate() + 1);
}
document.write(myDate);
</script>
</head>
<body>
<h1>My First JavaScript</h1>
<p id="demo">This is a paragraph.</p>
<button type="button" onclick="displayDate()">Display Date</button>
</body>
</html>
Roy
<==Update==>
I have use your code which works well but need to factor in after the First Tuesday has happened for the next month, I have tried this if statement but breaks.
function getTuesday() {
var datenow = new Date();
var d = new Date(),
month = d.getMonth(),
tuedays= [];
d.setDate(1);
// Get the first Monday in the month
while (d.getDay() !== 2) {
d.setDate(d.getDate() + 1);
}
// Get all the other Tuesdays in the month
while (d.getMonth() === month) {
tuedays.push(new Date(d.setHours(17,00,00,00)));
d.setDate(d.getDate() + 7);
}
If (d.getDate() >= datenow.getDate)
{
d.setMonth(d.getMonth() + 1);
document.write(tuedays[1]);
}
Else
{
document.write(tuedays[1]);
}
}
Use below function, that will give you current month Tuesdays.
function getTuesday() {
var d = new Date(),
month = d.getMonth(),
tuesdays= [];
d.setDate(1);
// Get the first Monday in the month
while (d.getDay() !== 2) {
d.setDate(d.getDate() + 1);
}
// Get all the other Tuesdays in the month
while (d.getMonth() === month) {
tuesdays.push(new Date(d.getTime()));
d.setDate(d.getDate() + 7);
}
return tuesdays;
}
I know that this is old but this is a function that i wrote based on what Sahal wrote that accepts a few additional features. Ill go through the arguments and returns below.
function getDates(dayString, month, year, first, allInYear) {
if (!dayString) { console.error('Missing required parameter: dayString is required.'); return; }
if (first === undefined || first === null) { first = false; }
if (allInYear === undefined || allInYear === null) { allInYear = false; }
if (year === undefined || year === null) { year = new Date().getFullYear(); }
var converted = false;
if (month === undefined || month === null) {
var temp = new Date();
if (temp.getDate() > 9) {
month = ((temp.getMonth() + 1) == 12) ? 11 : (temp.getMonth() + 1);
} else {
month = temp.getMonth();
}
converted = true;
}
if (typeof month === "string" && isNaN(parseInt(month))) {
month = month.toLowerCase().substring(0, 3);
switch (month) {
case "jan":
month = 0;
break;
case "feb":
month = 1;
break;
case "mar":
month = 2;
break;
case "apr":
month = 3;
break;
case "may":
month = 4;
break;
case "jun":
month = 5;
break;
case "jul":
month = 6;
break;
case "aug":
month = 7;
break;
case "sep":
month = 8;
break;
case "oct":
month = 9;
break;
case "nov":
month = 10;
break;
case "dec":
month = 11;
break;
default:
var temp = new Date();
if (temp.getDate() > 9) {
month = ((temp.getMonth() + 1) == 12) ? 11 : (temp.getMonth() + 1);
} else {
month = temp.getMonth();
}
converted = true;
break;
}
} else if (typeof month === "number" || (typeof month === "string" && !isNaN(parseInt(month)))) {
month = (!converted) ? parseInt(month) - 1 : month;
}
if (typeof year === "string" && !isNaN(parseInt(year)) || typeof year === "number") {
if (parseInt(year) / 1000 > 2) {
year = parseInt(year);
} else if (parseInt(year) / 10 >= 0 && parseInt(year) / 10 < 10) {
var temp2 = new Date().getFullYear();
year = (parseInt(Math.floor(temp2 / 100)) * 100) + parseInt(year);
}
} else if (typeof year === "string" && isNaN(parseInt(year))) {
if (year === "this") {
year = new Date().getFullYear();
} else if (year === "last") {
year = new Date().getFullYear() - 1;
} else if (year === "next") {
year = new Date().getFullYear() + 1;
} else {
console.warn('Year string not recognized, falling back to current year. (this, last, next).');
year = new Date().getFullYear();
}
}
var dates = [];
//hang in there this is going to get a doosie
var d = new Date(),
dow = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"],
getDow = function(sd, dowa) {
for (var i = 0; i < dowa.length; i++) {
var day = dowa[i];
if (sd.toLowerCase().substring(0, 3) == day) {
return i;
}
}
return -1;
},
di = getDow(dayString, dow),
getDIM = function(year, mon) {
var isLeap = ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0));
return [31, (isLeap ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][mon];
};
d.setFullYear(year);
d.setMonth(month, 1);
if (di == -1) { console.error('Range Error: Day of the week should be between sunday and saturday'); return; }
if (first && !allInYear) {
while (d.getDay() !== di) {
d.setDate(d.getDate() + 1);
}
return d;
} else if (first && allInYear) {
var tm = 0;
d.setMonth(tm, 1);
for (var i = tm; i <= 11; i++) {
while (d.getDay() !== di) {
d.setDate(d.getDate() + 1);
}
dates.push(new Date(d));
tm += 1;
d.setMonth(tm, 1);
}
return dates;
} else if (!first && !allInYear) {
var eom = getDIM(d.getFullYear(), d.getMonth());
for (var x = 1; x <= eom; x++) {
if (d.getDay() === di) {
dates.push(new Date(d));
}
d.setDate(d.getDate() + 1);
}
return dates;
} else if (!first && allInYear) {
var tm = 0;
for (var i = 0; i <= 11; i++) {
var eom = getDIM(d.getFullYear(), i),
dim = [];
d.setMonth(i, 1);
for (var x = 1; x <= eom && d.getMonth() == i; x++) {
if (d.getDay() === di) {
dim.push(new Date(d));
}
d.setDate(d.getDate() + 1);
}
dates.push(dim);
}
return dates;
} else {
return [];
}
}
So the only required argument is the day string, optionally you can set month,year,first or all in a month and all in a year or not, month and year default to current, and first and allInYear default to false, But you can set first in moth, by passing null or undefined to the month and year parameter.
month parameter accepts: null|undefined, number, or string eg 'July'
year parameter accepts: null|undefined, number 2 or 4 digit, string eg '19' or '2019' also 'last', 'this', 'next'
returns Date object,Array[Date object...], or Array[Array[Date object...]...]
This has been tested and should cover most situations...
Well, it's been over 8 years since I asked this question, and it showed up at the top result on Google for 'The first Tuesday of every month'. The original project is dead now, but I've gained more experience, I feel better placed to provide an answer.
First thing to note, is the original question wasn't obvious, and the title was just as ambiguous. The original goal, was to get the next occurrence of a first Tuesday of the month, so could be the current month, or next month depending on where you are in the month.
Because of the ambiguity in the question, I have tried to cover for those differences in interpretation in the answer.
My first function, is to get the occurrence of a specific day of the week for a given month and year. Thank you to #Amadan in the comments on one of the answers.
function GetFirstDayOfMonth(dayOfTheWeek, month, year){
const date = new Date(year, month, 1);
date.setDate(date.getDate() + ((7 + dayOfTheWeek) - date.getDay()) % 7)
return date;
}
The next function, gets the next occurrence of a first specified day of the week given a date.
function GetFirstNextFirstDayOfTheWeek(currentDate, day){
const returnValue = GetFirstDayOfMonth(day, currentDate.getMonth(), currentDate.getFullYear());
if(returnValue.getDate() < currentDate.getDate()){
return GetFirstNextFirstDayOfTheWeek(new Date(currentDate.getFullYear(), currentDate.getMonth() + 1), day);
}
return returnValue;
}
So to achieve the original question I can run the following example
const tuesday = 2;
function GetFirstNextFirstTuesday(){
return GetFirstNextFirstDayOfTheWeek(new Date(), tuesday);
}
To achieve getting the first Tuesday of a Month
const tuesday = 2;
function GetFirstTuesday(month, year){
return GetFirstDayOfMonth(tuesday, month, year);
}
And to finish getting all the first Tuesdays of a given year.
const tuesday = 2;
function GetFirstTuesdayOfEveryMonth(year){
const dates = [];
for (let index = 0; index < 12; index++) {
dates.push(GetFirstDayOfMonth(tuesday, index, year));
}
return dates;
}
function GetFirstDayOfMonth(dayOfTheWeek, month, year){
// Get the first day of the month
const date = new Date(year, month, 1);
// Set the date based on the day of the week.
date.setDate(date.getDate() + ((7 + dayOfTheWeek) - date.getDay()) % 7)
return date;
}
function GetFirstNextFirstDayOfTheWeek(currentDate, day){
const returnValue = GetFirstDayOfMonth(day, currentDate.getMonth(), currentDate.getFullYear());
if(returnValue.getDate() < currentDate.getDate()){
return GetFirstNextFirstDayOfTheWeek(new Date(currentDate.getFullYear(), currentDate.getMonth() + 1), day);
}
return returnValue;
}
const tuesday = 2;
function GetFirstTuesday(month, year){
return GetFirstDayOfMonth(tuesday, month, year);
}
function GetFirstNextFirstTuesday(){
return GetFirstNextFirstDayOfTheWeek(new Date(), tuesday);
}
function GetFirstTuesdayOfEveryMonth(year){
const dates = [];
for (let index = 0; index < 12; index++) {
dates.push(GetFirstDayOfMonth(tuesday, index, year));
}
return dates;
}
console.log(GetFirstNextFirstTuesday());
console.log(GetFirstTuesday(09, 2021));
console.log(GetFirstTuesdayOfEveryMonth(2022));
Hopefully, this can help anyone who may seem to stubble on this old post, and thank you to the people that did answer.

Add no. of days in a date to get next date(excluding weekends)

I have an date, i need to add no. of days to get future date but weekends should be excluded.
i.e
input date = "9-DEC-2011";
No. of days to add = '13';
next date should be "28-Dec-2011"
Here weekends(sat/sun) are not counted.
Try this
var startDate = "9-DEC-2011";
startDate = new Date(startDate.replace(/-/g, "/"));
var endDate = "", noOfDaysToAdd = 13, count = 0;
while(count < noOfDaysToAdd){
endDate = new Date(startDate.setDate(startDate.getDate() + 1));
if(endDate.getDay() != 0 && endDate.getDay() != 6){
//Date.getDay() gives weekday starting from 0(Sunday) to 6(Saturday)
count++;
}
}
alert(endDate);//You can format this date as per your requirement
Working Demo
#ShankarSangoli
Here's a newer version which avoid recreating a Date object on each loop, note that it's wrapped in a function now.
function calcWorkingDays(fromDate, days) {
var count = 0;
while (count < days) {
fromDate.setDate(fromDate.getDate() + 1);
if (fromDate.getDay() != 0 && fromDate.getDay() != 6) // Skip weekends
count++;
}
return fromDate;
}
alert(calcWorkingDays(new Date("9/DEC/2011"), 13));
Here is an elegant solution without any looping or external library:
function addBusinessDaysToDate(date, days) {
var day = date.getDay();
date = new Date(date.getTime());
date.setDate(date.getDate() + days + (day === 6 ? 2 : +!day) + (Math.floor((days - 1 + (day % 6 || 1)) / 5) * 2));
return date;
}
var date = "9-DEC-2011";
var newDate = addBusinessDaysToDate(new Date(date.replace(/-/g, "/")), 13);
console.log(newDate.toString().replace(/\S+\s(\S+)\s(\d+)\s(\d+)\s.*/, '$2-$1-$3')); // alerts "28-Dec-2011"
or you can be like this
function addWeekdays(date, weekdays) {
var newDate = new Date(date.getTime());
var i = 0;
while (i < weekdays) {
newDate.setDate(newDate.getDate() + 1);
var day = newDate.getDay();
if (day > 1 && day < 7) {
i++;
}
}
return newDate;
}
var currentDate = new Date('10/31/2014');
var targetDate = addWeekdays(currentDate, 45);
alert(targetDate);
Using moment.js:
const DATE_FORMAT = 'D-MMM-YYYY';
const SUNDAY = 0; // moment day index
const SATURDAY = 6; // moment day index
const WEEKENDS = [SATURDAY, SUNDAY];
function addBusinessDays(stringDate, numberOfDays, dateFormat = DATE_FORMAT) {
const date = moment(stringDate, dateFormat);
let count = 0;
while (count < numberOfDays) {
date.add(1, 'day');
// Skip weekends
if (WEEKENDS.includes(date.day())) {
continue;
}
// Increment count
count++;
}
return date.format(dateFormat);
}
// Test cases
console.log(addBusinessDays('3-Mar-2021', 1)); // 4-Mar-2021
console.log(addBusinessDays('3-Mar-2021', 2)); // 5-Mar-2021
console.log(addBusinessDays('3-Mar-2021', 3)); // 8-Mar-2021
console.log(addBusinessDays('3-Mar-2021', 4)); // 9-Mar-2021
console.log(addBusinessDays('3-Mar-2021', 5)); // 10-Mar-2021
console.log(addBusinessDays('9-Dec-2011', 13)); // 28-Dec-2011
console.log(addBusinessDays('10-Dec-2011', 13)); // 28-Dec-2011 (Saturday, so remain on Friday)
console.log(addBusinessDays('11-Dec-2011', 13)); // 28-Dec-2011 (Sunday, so remain on Friday)
console.log(addBusinessDays('12-Dec-2011', 13)); // 29-Dec-2011
console.log(addBusinessDays('13-Dec-2011', 13)); // 30-Dec-2011
console.log(addBusinessDays('14-Dec-2011', 13)); // 2-Jan-2012
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
This question is quite old, but all the previous answers are iterating over the days one by one. That could be inefficient for a large number of days. This works for me, assuming days is a positive int and the startDate is a working day:
function addWorkingDates(startDate, days) {
const current_day = startDate.getDay() - 1; // Week day, starting on Monday
const weekend_days = 2 * parseInt((current_day + days) / 5);
startDate.setDate(changed_to.getDate() + days + weekend_days);
}
addWorkingDates(new Date(),5)
For some reason it was more intuitive to me to try this recursively. This version doesn't account for holidays, but you could change the isValid function to check whatever.
function addWeekdaysToDate(date, numberToAdd) {
var isValid = function(d) { return d.getDay() !== 0 && d.getDay() !== 6 }
if(Math.abs(numberToAdd) > 1) {
return addWeekdaysToDate(
addWeekdaysToDate(date, Math.sign(numberToAdd)),
numberToAdd - Math.sign(numberToAdd)
)
} else if(Math.abs(numberToAdd) === 1) {
var result = new Date(date)
result.setDate(result.getDate() + Math.sign(numberToAdd))
if(isValid(result)) {
return result
} else {
return addWeekdaysToDate(result, Math.sign(numberToAdd))
}
} else if(numberToAdd === 0) {
return date
}
return false
}
console.log(addWeekdaysToDate(new Date(), 1))
console.log(addWeekdaysToDate(new Date(), 5))
console.log(addWeekdaysToDate(new Date(), -7))
In certain browsers you may need a polyfill for Math.sign:
Math.sign = Math.sign || function(x) {
x = +x; // convert to a number
if (x === 0 || isNaN(x)) {
return Number(x);
}
return x > 0 ? 1 : -1;
}
try this solution
<script language="javascript">
function getDateExcludeWeekends(startDay, startMonth, startYear, daysToAdd) {
var sdate = new Date();
var edate = new Date();
var dayMilliseconds = 1000 * 60 * 60 * 24;
sdate.setFullYear(startYear,startMonth,startDay);
edate.setFullYear(startYear,startMonth,startDay+daysToAdd);
var weekendDays = 0;
while (sdate <= edate) {
var day = sdate.getDay()
if (day == 0 || day == 6) {
weekendDays++;
}
sdate = new Date(+sdate + dayMilliseconds);
}
sdate.setFullYear(startYear,startMonth,startDay + weekendDays+daysToAdd);
return sdate;
}
</script>
If you want to get the next working day, from a specific date, use the following code...
function getNextWorkingDay(originalDate) {
var nextWorkingDayFound = false;
var nextWorkingDate = new Date();
var dateCounter = 1;
while (!nextWorkingDayFound) {
nextWorkingDate.setDate(originalDate.getDate() + dateCounter);
dateCounter++;
if (!isDateOnWeekend(nextWorkingDate)) {
nextWorkingDayFound = true;
}
}
return nextWorkingDate;
}
function isDateOnWeekend(date) {
if (date.getDay() === 6 || date.getDay() === 0)
return true;
else
return false;
}
Try this
function calculate() {
var noOfDaysToAdd = 13;
var startDate = "9-DEC-2011";
startDate = new Date(startDate.replace(/-/g, "/"));
var endDate = "";
count = 0;
while (count < noOfDaysToAdd) {
endDate = new Date(startDate.setDate(startDate.getDate() + 1));
if (endDate.getDay() != 0 && endDate.getDay() != 6) {
count++;
}
}
document.getElementById("result").innerHTML = endDate;
}
<div>
Date of book delivery: <span id="result"></span><br /><br />
<input type="button" onclick="calculate();" value="Calculate" />
<br>
<br>
</div>

date difference in months in javascript

Need date Difference in terms of months.
If I give the FromDate as 1st Feb,2011 and ToDate as 2nd April 2011 then Its should give result as 2.2.
That means It should calculate the months first then the number of days in the decimal value.
See if date difference is 3 months and 22 days then It should give the difference as 3.22
Is it possible through the Javascript.
var date1 = new Date(2011,1,1);
var date2 = new Date(2011,3,2);
var diffYears = date2.getFullYear()-date1.getFullYear();
var diffMonths = date2.getMonth()-date1.getMonth();
var diffDays = date2.getDate()-date1.getDate();
var months = (diffYears*12 + diffMonths);
if(diffDays>0) {
months += '.'+diffDays;
} else if(diffDays<0) {
months--;
months += '.'+(new Date(date2.getFullYear(),date2.getMonth(),0).getDate()+diffDays);
}
alert(months);
See http://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/demos/calendar/time-cajita.js# for an RFC 2445 date/time library.
time.durationBetween returns a duration value that is the difference between two dates.
You can see usage examples in the unittests
not exact but you can get a rough estimate with this:
var d=new Date(2010,00,01); //start date
var dd=new Date(2010,11,31); //end date
var dif=dd-d //get difference in milliseconds
var m=dif/(86400000*30); //1000*60*60*24=>86400000 gives one day
It gives 12.133~ for above dates.
the example below gives result 2.2 for your dates
var d1 = new Date(2011, 1, 1);
var d2 = new Date(2011, 3, 2);
var ydiff = d2.getYear() - d1.getYear();
var mdiff = d2.getMonth() - d1.getMonth();
var ddiff = 1 + d2.getDate() - d1.getDate();
var diff = (ydiff*12 + mdiff + ".") + ddiff;
alert(diff);
I hope that it helps. 100% works.
var startDate = '13.06.2013'; // for example (i got it from input)
var endDate = '12.02.2016'; // for example
var temp_sd = explode('.', startDate);
var temp_ed = explode('.', endDate);
var row_id = $(this).attr('row_id');
var m_arr = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; // 365 days in year
var m_arr_vis = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; // 366 days
var temp_year = parseInt(temp_sd[2]);
var temp_month = parseInt(temp_sd[1]);
var daysInM, temp_s, temp_e, m_diff = 0;
while(true) {
if(temp_month === parseInt(temp_sd[1])) {
temp_s = parseInt(temp_sd[0]);
} else {
temp_s = 1;
}
if((temp_year%4) === 0) {
daysInM = m_arr_vis[temp_month-1];
} else {
daysInM = m_arr[temp_month-1];
}
if(temp_month === parseInt(temp_ed[1])) {
temp_e = parseInt(temp_ed[0]);
} else {
temp_e = daysInM;
}
m_diff += (temp_e-temp_s+1)/daysInM;
//alert(temp_s+' -> '+temp_e+' . '+temp_month+' . '+temp_year);
//alert(temp_e-temp_s+1);
//alert(daysInM);
if((temp_year === parseInt(temp_ed[2]))&&(temp_month === parseInt(temp_ed[1]))) break;
// inc temp_month
if(temp_month<12) {
temp_month++;
} else {
temp_month = 1;
// inc temp_years
temp_year++;
}
}
var months = Number(m_diff).toFixed(7);
...
function explode( delimiter, string ) { // Split a string by string
//
// + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + improved by: kenneth
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
var emptyArray = { 0: '' };
if ( arguments.length != 2
|| typeof arguments[0] == 'undefined'
|| typeof arguments[1] == 'undefined' )
{
return null;
}
if ( delimiter === ''
|| delimiter === false
|| delimiter === null )
{
return false;
}
if ( typeof delimiter == 'function'
|| typeof delimiter == 'object'
|| typeof string == 'function'
|| typeof string == 'object' )
{
return emptyArray;
}
if ( delimiter === true ) {
delimiter = '1';
}
return string.toString().split ( delimiter.toString() );
}

Categories