Reputation: 3108
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
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
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