Parampal Pooni
Parampal Pooni

Reputation: 3108

Count the number of anniversaries between two dates?

What is the easiest way in Javascript to calculate the number of anniversaries between two dates.

My attempt:

module.exports.countAnniversariesBetweenTwoDates = (start_date, end_date, anniversary_date) => {

  if (start_date == end_date) {
    return 0;
  }

  let start_date_year = start_date.getFullYear();
  let end_date_year = end_date.getFullYear();
  let anniversary_year = anniversary_date.getFullYear();
  let start_date_month_and_day = Number(('0' + (start_date.getMonth() + 1)).slice(-2) + '' + ('0' + start_date.getDate()).slice(-2));
  let end_date_month_and_day = Number(('0' + (end_date.getMonth() + 1)).slice(-2) + '' + ('0' + end_date.getDate()).slice(-2));
  let anniversary_date_month_and_day = Number(('0' + (anniversary_date.getMonth() + 1)).slice(-2) + '' + ('0' + anniversary_date.getDate()).slice(-2));

  let anniversary_count = 0;

  // special case for start year
  if (start_date_month_and_day < anniversary_date_month_and_day) {
    anniversary_count++;
  }

  let temp_start_date_year = start_date_year + 1;
  while(temp_start_date_year < end_date_year) {
    anniversary_count++;
    temp_start_date_year++;
  }

  // special case for end year
  if (end_date_month_and_day > anniversary_date_month_and_day) {
    anniversary_count++;
  }
  return anniversary_count;
}

Upvotes: 0

Views: 418

Answers (2)

Karl-Henry Martinsson
Karl-Henry Martinsson

Reputation: 2795

If you use moment.js you can just get the difference between two dates as years, the use Math.floor() to round down to the nearest full number of years:

yearDiff = Math.floor(moment(new Date(endDate)).diff(new Date(startDate),'years'));

Edit: The code above can be simplified a bit more:

yearDiff = moment(endDate).diff(startDate,'years');

You may have to write some additional code to handle time periods of less than a year, or some other special cases.

You could of course loop through the dates similar to how you do it:

var startDate = "03/08/2019";
var endDate = "01/01/2022";
var anniversary = "03/07/2015";
var anniversaryCount = 0;

var counterMoment = moment(startDate);
while (counterMoment.isSameOrBefore(endDate)) {
    var anniversaryThisYear = moment(anniversary).year(counterMoment.year());
    if (counterMoment.isSame(anniversaryThisYear)) {
        anniversaryCount++;
    }
    counterMoment.add(1,'day');
}
alert("Number of anniversaries: "+anniversaryCount);

It all depends on what the end result is and how you plan to use the value.

Upvotes: 1

Steve
Steve

Reputation: 10886

Here's one that accounts for leap years:

function validDate(year, month, day) {
  var testDate = new Date(year, month, day);
  return testDate.getFullYear() === year && testDate.getMonth() === month && testDate.getDate() === day;
}

function countAnniversaries(begin, end, anniversary) {
  var countDate = new Date(anniversary.getTime());
  var anniversaries = 0;
  var countYear = begin.getFullYear();
  var anniversaryMonth = anniversary.getMonth();
  var anniversaryDay = anniversary.getDate();
  countDate.setFullYear(countYear);
  while (countDate.getTime() <= end.getTime()) {
    if (validDate(countYear, anniversaryMonth, anniversaryDay) && countDate.getTime() >= begin.getTime()) {
      anniversaries++;
    }
    countYear++;
    countDate.setFullYear(countYear);  
    countDate.setMonth(anniversaryMonth);
    countDate.setDate(anniversaryDay);
  }
  return anniversaries;
}

console.log(countAnniversaries(new Date('Feb 1, 2012'), new Date('Feb 4, 2026'), new Date('Feb 2, 2012')))
console.log(countAnniversaries(new Date('Feb 1, 2012'), new Date('Feb 4, 2026'), new Date('Feb 29, 2012')))

Upvotes: 1

Related Questions