I am trying to add/subtract an integer to the element of array. my function is
var addToMonth = function (date, monthsToAdd) {
var tempDate = date.split("-");
tempDate[1] = parseInt(tempDate[1]) + monthsToAdd;
tempDate[1] = 0 + tempDate[1];
console.log("TempDate "+tempDate[1]);
tempDate = tempDate.join("-");
console.log("Added TempDate: "+tempDate);
return tempDate;
}
The acceptable date string is: date = "2016-04-05"
. If call the function as addToMonth(date,1)
. The output is correct that is 2016-05-05
. But when I call it as addToMonth(date, -1)
. It doesn't work. What is the correct way to do it?
I am trying to add/subtract an integer to the element of array. my function is
var addToMonth = function (date, monthsToAdd) {
var tempDate = date.split("-");
tempDate[1] = parseInt(tempDate[1]) + monthsToAdd;
tempDate[1] = 0 + tempDate[1];
console.log("TempDate "+tempDate[1]);
tempDate = tempDate.join("-");
console.log("Added TempDate: "+tempDate);
return tempDate;
}
The acceptable date string is: date = "2016-04-05"
. If call the function as addToMonth(date,1)
. The output is correct that is 2016-05-05
. But when I call it as addToMonth(date, -1)
. It doesn't work. What is the correct way to do it?
- 2 What is not working? You getting errors? – void Commented Apr 5, 2016 at 7:55
-
This seems to work fine. Is your problem with padding the month with
0
? – Jon Surrell Commented Apr 5, 2016 at 7:57 -
tempDate[1] = '' + 0 + tempDate[1];
to pad it with0
..Rest of things look good! – Rayon Commented Apr 5, 2016 at 7:58
2 Answers
Reset to default 4Original 2016
The selected answer is actually incorrect as the question asks how to add months, not days. The correct solution is:
function addToMonth( date, months ) {
var d = new Date( date || new Date() );
d.setMonth( d.getMonth() + (months || 0), d.getDate());
return d;
}
Show and then run the code snippet to view demo.
I've also up voted the question ... because it does show effort and dates are tricky to work with even for experienced coders (especially when time zones are involved). That's why there are libraries like monment.js and others. For more information on the Date object see: MDN Date
function addToMonth( date, months ) {
var d = new Date( date || new Date() );
d.setMonth( d.getMonth() + (months || 0), d.getDate());
return d;
}
// Test Data
var html = '', iso, step = 1;
[
'4/5/2016',
'4/5/2016 01:00 GMT',
'2016-04-05',
'2016-04-05T00:00:00',
'2016-04-05T23:59:59',
'2016-04-05T23:59:59Z',
'2016',
'4/5/2016',
undefined,
null,
0,
'',
(new Date())
].forEach(function(v,i) {
iso = addToMonth( v, -1).toISOString().split('T').shift();
html += '<tr><td>' + v + '</td><td>-1</td><td>' + iso + '</td></tr>';
iso = addToMonth( v, 1).toISOString().split('T').shift();
html += '<tr><td>' + v + '</td><td>+1</td><td>' + iso + '</td></tr>';
});
stdout.innerHTML = '<table>' + html + '</table>';
table {
border-collapse: collapse;
background-color: white;
}
td {
max-width: 10em;
min-width: 4em;
border: 1px lightgray solid;
padding: 2px;
overflow: hidden;
white-space: nowrap;
font-family: monospace;
}
tr:nth-child(odd) {
background-color: aliceblue;
}
<div id="stdout"></div>
Update 2023
A menter noted the edge case where the day of the month is greater than the target maximum. In this case the function uses the default Date.setMonth behavior, which can spill over into the following month, e.g., 31 Jan + 1 month = 3 Mar rather than 28 Feb. Since the question doesn't specify how to handle these cases it seems reasonable to use the expected behavior and not try to guess what OP wants.
The menter also noted that getDate
is redundant in
d.setMonth( d.getMonth() + (months || 0), d.getDate())
True, and it can be shortened to
d.setMonth( d.getMonth() + (months || 0))
Interestingly, this change didn't appear to make any difference in performance (Chrome 100k loops).
Alternative code that incorporates menter suggestions:
function addToMonth( date, months ) {
let d = new Date( date || new Date() ), n = d.getDate();
d.setMonth( d.getMonth() + (months || 0));
if (d.getDate() < n) d.setMonth( d.getMonth(), 0);
return d;
}
Yours is not a right approach:
parseInt
should always use base 10 if working with decimals.addToMonth("2016-31-03", 1)
will give 2016-32-03. WRONG X.addToMonth("2016-01-03", -1)
will give 2016-00-03. WRONG X.- The way you are padding the
0
is not right. (Find out why.)
Use setDate
and getDate
functions on date instead.
var addToMonth = function (date, monthsToAdd) {
var d = new Date(date);
d.setDate(d.getDate()+monthsToAdd);
return d;
}