You really don't need a library. To add one month to a date is fairly straight forward, starting with:
date.setMonth(date.getMonth() + 1);
This maintains the time associated with the date, even over daylight saving boundaries, but can push the date beyond the end of the following month, e.g. adding 1 month to Jan 31 gives 31 Feb which goes to 2 or 3 March (depending on if it's a leap year or not).
So there needs to be a check that if the date isn't the same, it's rolled over a month so set it to the last day of the previous month. Written as a function to add an arbitrary number of months:
function addMonths(date, months) {
var d = date.getDate();
date.setMonth(date.getMonth() + +months);
if (date.getDate() != d) {
date.setDate(0);
}
return date;
}
// Add 12 months to 29 Feb, 2016
var d = new Date(2016,1,29)
console.log(addMonths(d, 12).toString()); // 28 Feb 2017
Adding is even easier, see Add +1 to current date which is easily adapted to add any number of days (which means this question is really a duplicate).
So, back to your code.
Here is the GetDateSchedulerFormatted function
function GetDateSchedulerFormatted(date) {
function pad(s) {
return (s < 10) ? '0' + s : s;
}
var d = new Date(date);
// yyy-MM-dd
return [pad(d.getDate()),
pad(d.getMonth() + 1),
d.getFullYear()
].join('/') + " " +
pad(d.getHours()) + ":" +
pad(d.getMinutes());
}
// In this example the code returns the correct date
var activity = {};
activity.startDate = '2017-07-02T00:00:00-08:00';
var startDate = GetDateSchedulerFormatted(activity.startDate); //start date 07/02/2017 00:00 d/m/yyy
var newDate = new Date(startDate); // returns Tue Aug 01 2017 00:00:00 GMT-0700 (Pacific Daylight Time) also 1 day off
var endDate = GetDateSchedulerFormatted(new Date(newDate.setTime(newDate.getTime() + 30 * 86400000))); //returns
correct date 01/08/2017
Your issue is that you start with a valid ISO 8601 formatted string, '2017-07-02T00:00:00-08:00' but then reformat it into your own format in your own timezone (something like '02/07/2017 00:00' if your timezone is -0800), then parse that with the Date constructor, which is a very bad idea. It's likely treated as 7 February so I don't know how you can say it returns the correct date when you started with 2 July. And adding 1 month should be 2 August, not 1 August (though you did add 30 days rather than 1 month). Lastly, if you cross a daylight saving boundary, you may lose or pick up an hour so the date may be 23:00 the day before or go from 00:00 to 01:00.
Note that you have:
07/02/2017 00:00 d/m/yyy
^^^^^^^
which is not 2 July, it's 7 February.
The rest of your issues are similar.
Anyhow, if you're happy with using a library, fine. Just thought I'd point out where you'd gone wrong.
Here's your code adapted so it runs here, showing the errors:
function GetDateSchedulerFormatted(date) {
function pad(s) {
return (s < 10) ? '0' + s : s;
}
var d = new Date(date);
// yyy-MM-dd
return [pad(d.getDate()),
pad(d.getMonth() + 1),
d.getFullYear()
].join('/') + " " +
pad(d.getHours()) + ":" +
pad(d.getMinutes());
}
// In this example the code returns the correct date
var activity = {};
activity.startDate = '2017-07-02T00:00:00-08:00';
var startDate = GetDateSchedulerFormatted(activity.startDate); //start date 07/02/2017 00:00 d/m/yyy
var newDate = new Date(startDate); // returns Tue Aug 01 2017 00:00:00 GMT-0700 (Pacific Daylight Time) also 1 day off
var endDate = GetDateSchedulerFormatted(new Date(newDate.setTime(newDate.getTime() + 30 * 86400000))); //returns correct date 01/08/2017 00: 00 d / m / yyyy
console.log('activity.startDate: ' + activity.startDate +
'\nstartDate : ' + startDate +
'\nnewDate : ' + GetDateSchedulerFormatted(newDate) +
'\nendDate : ' + endDate);
// In this next example it returns the date 1 year off
activity.startDate = '2016-12-12T00:00:00-08:00';
var startDate = GetDateSchedulerFormatted(activity.startDate); //returns 12/12/2016 00:00 d/m/yyy
var newDate = new Date(startDate); // returns Wed Jan 11 2017 00:00:00 GMT-0800 1 month ahead
var endDate = GetDateSchedulerFormatted(new Date(newDate.setTime(newDate.getTime() + 30 * 86400000))); //returns 11/01/2017 00:0 d/m/yyy
console.log('activity.startDate: ' + activity.startDate +
'\nstartDate : ' + startDate +
'\nnewDate : ' + GetDateSchedulerFormatted(newDate) +
'\nendDate : ' + endDate);
// In this example the same exact date is returned
activity.startDate = '2017-02-01T00:00:00-08:00';
var startDate = GetDateSchedulerFormatted(activity.startDate); //returns 01/02/2017 00:00 d/m/yyy
var newDate = new Date(startDate); // returns Wed Feb 01 2017 00:00:00 GMT-0800
var endDate = GetDateSchedulerFormatted(new Date(newDate.setTime(newDate.getTime() + 30 * 86400000))); //returns 01/02/2017 00:00 the same date, it 's not 30 days ahead
console.log('activity.startDate: ' + activity.startDate +
'\nstartDate : ' + startDate +
'\nnewDate : ' + GetDateSchedulerFormatted(newDate) +
'\nendDate : ' + endDate);
// Then in this final example I get NaN / NaN / NaN NaN: NaN
activity.startDate = '2017-02-25T00:00:00-08:00';
var startDate = GetDateSchedulerFormatted(activity.startDate); //returns 25/02/2017 00:00 d/m/yyy
var newDate = new Date(startDate); // returns invalid date
var endDate = GetDateSchedulerFormatted(new Date(newDate.setTime(newDate.getTime() + 30 * 86400000))); //returns NaN/NaN/NaN NaN:NaN
console.log('activity.startDate: ' + activity.startDate +
'\nstartDate : ' + startDate +
'\nnewDate : ' + GetDateSchedulerFormatted(newDate) +
'\nendDate : ' + endDate);