admin管理员组

文章数量:1430958

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?

Share Improve this question edited Apr 5, 2016 at 8:01 Liam 29.8k28 gold badges139 silver badges203 bronze badges asked Apr 5, 2016 at 7:52 uvishereuvishere 4308 silver badges22 bronze badges 3
  • 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 with 0..Rest of things look good! – Rayon Commented Apr 5, 2016 at 7:58
Add a ment  | 

2 Answers 2

Reset to default 4

Original 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:

  1. parseInt should always use base 10 if working with decimals.
  2. addToMonth("2016-31-03", 1) will give 2016-32-03. WRONG X.
  3. addToMonth("2016-01-03", -1) will give 2016-00-03. WRONG X.
  4. 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;
}

本文标签: javascriptHow do I add and subtract months from a dateStack Overflow