Reputation: 251
I am trying to add days to a date. I am taking input from the user where I have separate input boxes for the each field like no. of years, no of months and no of days like this.
as you can see in the 2nd input field row I am accepting no of years, days, months, etc. and in First row I am getting a proper date like : 2020 10 05 00 00 00 and then passing them to date constructor to gate date.
ex. Date firstdate = new Date(2020, 10, 05, 00, 00,00);
and I am adding days to the above date using the following function
Date.prototype.addDays = function(days) {
var date = new Date(this.valueOf());
date.setDate(date.getDate() + days);
return date;
}
I am adding days to the previous date by calling a function like this. var newdate = firstdate.addDays(totaldays);
Now the problem is while I am calculating days it is not including leap years and months with their specified date. because I am calculating days like this way:
totaldays = (years * 365) + (months * 30) + days;
What is the way so I can add days perfectly? for example, if the user entered date like
2020 12 10 00 00 00
and add the number of days and years like this
1 year 3 months 0 days 00 00 00
so it should ideally calculate 3 months that is January, February, march, as the user has entered the date of December so next three months date should be added.
SO How do I get the perfect number of days? Sorry, this question can feel so long or improper. but I am working on this from a week. Note: I cannot use any external link, API, Library as this is a school project.
Any help will be great. also sorry for my English. I'm not a native speaker.
Upvotes: 2
Views: 1235
Reputation: 147353
This is a duplicate of other questions:
To summarise some of the issues:
There are other quirks with leap years and month lengths not mentioned above, such as 31 Aug + 1 month gives 1 Oct, because adding a month in August adds 31 days.
So you can either add business rules to deal with the quirks, or just let them happen.
In reagard to adding years, months and days, that can be done in one call to setFullYear:
date.setFullYear(date.getFullYear() + yearsToAdd,
date.getMonth() + monthsToAdd,
date.getDate() + daysToAdd);
Adding them all at once can have a different result to adding them one at a time.
Given that you are getting values for the year, month, day, etc. then the values to add, you can simply add corresponding values (ensuring you convert strings to numbers before adding) and call the Date constructor once:
let date = new Date(startYear + yearsToAdd,
startMonth - 1 + monthsToAdd, // Assuming user enters calendar month
startDay + daysToAdd,
startHour + hoursToAdd,
startMinute + minutesToAdd,
startSecond + secondsToAdd);
Upvotes: 0
Reputation: 1074028
Let the Date
object do it for you, by using getFullyear
/setFullYear
, getMonth
/setMonth
, and getDate
/setDate
. They handle rollover and leap years:
const yearsToAdd = 1;
const monthsToAdd = 3;
const daysToAdd = 0;
const date = new Date(2020, 12 - 1, 10);
console.log(date.toString());
date.setFullYear(date.getFullYear() + yearsToAdd);
date.setMonth(date.getMonth() + monthsToAdd);
date.setDate(date.getDate() + daysToAdd);
console.log(date.toString());
Just as an example of handling leap years, here's that code adding two days to Feb 28th 2020 (which was a leap year, so there was a Feb 29th):
const yearsToAdd = 0;
const monthsToAdd = 0;
const daysToAdd = 2;
const date = new Date(2020, 2 - 1, 28);
console.log(date.toString());
date.setFullYear(date.getFullYear() + yearsToAdd);
date.setMonth(date.getMonth() + monthsToAdd);
date.setDate(date.getDate() + daysToAdd);
console.log(date.toString());
Notice how it goes to March 1st, not March 2nd, as it does in 2019:
const yearsToAdd = 0;
const monthsToAdd = 0;
const daysToAdd = 2;
const date = new Date(2019, 2 - 1, 28);
console.log(date.toString());
date.setFullYear(date.getFullYear() + yearsToAdd);
date.setMonth(date.getMonth() + monthsToAdd);
date.setDate(date.getDate() + daysToAdd);
console.log(date.toString());
Upvotes: 1