简体   繁体   中英

JavaScript add days not incrementing the month

I know this question has come up many times and I have used the recommended solution to created my function, but I have used it to scroll a calendar along the next/prev 4 weeks.

What seems to happen is that the first time it calculates d + 28 it is correct, but when the outputted result is used in the function it does not work.

Examples from console log:

Press 'next' first time:

start Before = Tue Jul 28 2015 21:53:20 GMT+0100 (GMT Daylight Time)
start After = Tue Aug 25 2015 21:53:22 GMT+0100 (GMT Daylight Time)

Press 'next' a second time:

start Before = Tue Aug 25 2015 21:53:22 GMT+0100 (GMT Daylight Time)
start After = Sat Aug 22 2015 21:53:28 GMT+0100 (GMT Daylight Time)

and so it goes on.

HTML:

 <!DOCTYPE html>
 <html ng-app="testApp">
 <head>
  <script src="https://code.angularjs.org/1.4.2/angular.js" data-require="angular.js@1.4.2" data-semver="1.4.2"></script>
  <link href="style.css" rel="stylesheet" />
  <script src="script.js"></script>
 </head>
 <body ng-controller="testController">
  <h1>Hello Plunker!</h1>
  <input type="button" ng-click="prevWeeks(start)" value="subtract 28 days" ng-model="start" />
  <input type="button" ng-click="nextWeeks(start)" value="add 28 days" ng-model="start" />
  <hr />
  <div>{{start}}</div>
 </body>
 </html>

JS:

var testApp = angular.module('testApp', []);

testApp.controller('testController', function($scope) {
  $scope.start = new Date();

  $scope.nextWeeks = function(d) {
    console.log('Next:');
    console.log('  start Before = ' + d);
    $scope.start = addDays(d, 28);
    console.log('    start After = ' + $scope.start);
    console.log('\n');
    }

  $scope.prevWeeks = function(d) {
    console.log('Previous');
    console.log('  start Before = ' + d);
    $scope.start = addDays(d, -28);
    console.log('    start After = ' + d);
    console.log('\n');
  }

});

function addDays(d, qty) {
  var dd = d.getDate();
  var mm = d.getMonth() + 1;
  var yyyy = d.getFullYear();
  if (dd < 10) dd = '0' + dd;
  if (mm < 10) mm = '0' + mm;
  var moreDate = new Date(yyyy, mm - 1, dd);

  var someDate = new Date();
  someDate.setDate(moreDate.getDate() + qty);

  return someDate;
}

On Plnkr here .

Any ideas? Have I slipped up somewhere?

Your function can be simplified greatly, because the Date type automatically takes care of adjusting the month when the date goes out of range.

function addDays(d, qty) {
    var dd = d.getDate();
    var mm = d.getMonth();
    var yyyy = d.getFullYear();
    return new Date(yyyy, mm, dd + qty);
}

Another way would be:

function addDays(d, qty) {
    var newDate = new Date(d.getTime()); // Copy date
    newDate.setDate(d.getDate() + qty);
    return newDate;
}

Since ways to fix this has already been provided let me tell you why your way doesn't work. You first create moreDate which adjusts the year and month to the intended values but after that you create someDate which is initialized as the current day with current month and current year. You add qty to the date and set that on someDate . The calculation then is relative to today and not relative to the date provided as argument. For example,

var d = new Date(); //July 28 2015
d = addDays(d,28); //Aug 25 2015,works because we added 28 days to today
d = addDays(d,28); //Aug 22 2015!! Looks wrong, but is it?

The last call clearly looks wrong but it isn't really. Stepping through your code:

  /*more code*/
  var moreDate = new Date(yyyy, mm - 1, dd); //Aug 25 2015

  var someDate = new Date(); //Catch!! July 28 2015
  someDate.setDate(moreDate.getDate() + qty); //Catch!!
  //the call above added 28+25 days to today which is Aug 22 2015
  return someDate;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM