最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

javascript - Difference between two dates without leap day - Stack Overflow

matteradmin4PV0评论

I have Start Date and End Date and I have to get difference between these two dates, but the condition is, I have to exclude 29th Feb if it is leap year. I am able to get difference between two dates using momentJS. But how to exclude 29th feb if it is in that date range.

For Ex:

//For Leap Year
var startDate = moment('2020-02-27')
var endDate = moment('2020-03-01')
console.log('Diff in leap year', endDate.diff(startDate, 'days')); //Result: 3



var startDate1 = moment('2018-02-27')
var endDate1 = moment('2018-03-01')
console.log('Diff in non leap year', endDate1.diff(startDate1, 'days')); //Result: 2 
<script src=".js/2.21.0/moment.min.js"></script>

I have Start Date and End Date and I have to get difference between these two dates, but the condition is, I have to exclude 29th Feb if it is leap year. I am able to get difference between two dates using momentJS. But how to exclude 29th feb if it is in that date range.

For Ex:

//For Leap Year
var startDate = moment('2020-02-27')
var endDate = moment('2020-03-01')
console.log('Diff in leap year', endDate.diff(startDate, 'days')); //Result: 3



var startDate1 = moment('2018-02-27')
var endDate1 = moment('2018-03-01')
console.log('Diff in non leap year', endDate1.diff(startDate1, 'days')); //Result: 2 
<script src="https://cdnjs.cloudflare./ajax/libs/moment.js/2.21.0/moment.min.js"></script>

I am expecting uniform result for leap and non leap year, or simply want to exclude 29th feb from calculation. Difference can be more than a year.

Is there any optimal solution to do it?

Share Improve this question edited Mar 5, 2018 at 7:27 void 36.7k10 gold badges69 silver badges111 bronze badges asked Mar 5, 2018 at 7:00 Laxmikant DangeLaxmikant Dange 7,7186 gold badges43 silver badges67 bronze badges 1
  • 1 the best you can do is check if is leap year by startDate.isLeapYear() and if so, you subtract one more day from result – guijob Commented Mar 5, 2018 at 7:10
Add a ment  | 

4 Answers 4

Reset to default 3

You can check if it is a leap year using .isLeapYear() and if so, you subtract one more day from your result:

function diffDates(startDate, endDate) {
  var diff = endDate.diff(startDate, 'days');

  while(startDate < endDate) {
    if(startDate.isLeapYear() && 
      moment(`${startDate.year()}-02-29`).isBetween(startDate, endDate)) {
      diff--;
    }
    startDate.year(startDate.year() + 1);
  }
  return diff;
}

var startDate = moment('2020-02-27')
var endDate = moment('2020-03-01')

console.log('Leap year days diff: ' + diffDates(startDate, endDate)); // 2

startDate = moment('2018-02-27')
endDate = moment('2018-03-01')
console.log('Non leap year days diff: ' + diffDates(startDate, endDate)); // 2

startDate = moment('2019-02-27')
endDate = moment('2020-03-01')
console.log('Between leap year days diff: ' + diffDates(startDate, endDate)); // 367

I've added a clause to know if your dates is between feb 29 when is a leap year using .isBetween(), and created a while loop to subtract 1 from diff every time a leap day is within interval.

See it working here.

Using .isLeapYear() you can iterate over all the years between date range and get the expected result

function dateDiff(startStr, endStr) {
  var startDate = moment(startStr);
  var endDate = moment(endStr);
  var diff = endDate.diff(startDate, 'days');
  for (var year = startDate.year(); year <= endDate.year(); year++) {
    var date = moment(year + '-02-29');
    if (date.isBetween(startDate,endDate) && date.isLeapYear()) {
        diff -= 1;
    }
  }
  return diff;
}

console.log(dateDiff('2020-02-27', '2020-03-01'));
console.log(dateDiff('2018-02-27', '2018-03-01'));

You can check if the startDate is a leap year or not using .isLeapYear() and then subtract 1 accordingly.

function getDiff(startDate, endDate){
  var isLeapYear = startDate.isLeapYear();
  return endDate.diff(startDate, 'days') - (isLeapYear?1:0);
}


var startDate = moment('2020-02-27')
var endDate = moment('2020-03-01')
console.log('Diff in leap year', getDiff(startDate, endDate)); 

var startDate1 = moment('2018-02-27')
var endDate1 = moment('2018-03-01')
console.log('Diff in non leap year',getDiff(startDate1, endDate1));
<script src="https://cdnjs.cloudflare./ajax/libs/moment.js/2.21.0/moment.min.js"></script>

You can try something like this:

  • Check if the selected year is a leap year.
  • If yes, check if date range covers 29th Feb
  • If yes, subtract 1 else 0

function getDiff(startDate, endDate){
  var dayToExclude = moment('29/02/' + startDate.year(), 'DD/MM/YYYY');
  var excludeDays = startDate.isLeapYear() && startDate.isBefore(dayToExclude) && endDate.isAfter(dayToExclude) ? 1 : 0;
  return endDate.diff(startDate, 'days') - excludeDays;
}


var startDate = moment('2020-02-27')
var endDate = moment('2020-03-01')
console.log('Diff in leap year', getDiff(startDate, endDate)); 

var startDate1 = moment('2018-02-27')
var endDate1 = moment('2018-03-01')
console.log('Diff in non leap year',getDiff(startDate1, endDate1));
<script src="https://cdnjs.cloudflare./ajax/libs/moment.js/2.21.0/moment.min.js"></script>

Post a comment

comment list (0)

  1. No comments so far