It might seem an error to pass in the currentYear without checking if it rolled back a year in the daysInPreviousMonth function, but it doesn’t affect the result as the only code using the year passed into daysInMonth is the isLeapYear check and for that case it only applies if the month passed in is 2 (February) in which case it is impossible for the year to have rolled back.

]]>dateDiff Function:

//Add code before here to first make sure startDate is in fact before endDate. If not, then swap them.

yearsDiff = endYear – startYear;

if (endMonth > startMonth) {

monthsDiff = endMonth – startMonth;

} else {

yearsDiff–;//Take off the partial year we counted.

monthsDiff = endMonth + 12 – startMonth

}

if (endDay > startDay) {

daysDiff = endDay – startDay;

} else {

daysDiff = daysInPreviousMonth(endMonth, endYear) – startDay + endDay;

monthsDiff–;//Take off the partial month we counted.

}

weeksDiff = 0;

while (daysDiff > 7) {

weeksDiff++;

daysDiff -= 7;

}

Anyone want to code this pseudo up and test it? lol

Are there any errors or special cases this one misses?

Just be careful in coding daysInMonth to account for leap years.

daysInPreviousMonth Function:

return daysInMonth((monthPassedIn + 12 – 1) % 12, currentYear);

daysInMonth Function:

usualDaysInMonth = [31, 28, …];

daysInMonth = usualDaysInMonth[monthPassedIn];

if (monthPassedIn == 2 && isLeapYear(yearPassedIn)){

daysInMonth++;

}

return daysInMonth;

isLeapYear Function:

leapYear = false;

if (yearPassedIn % 4 == 0) {

leapYear = true;

if (yearPassedIn % 100 == 0) {

leapYear = false;

if (yearPassedIn % 400 == 0) {

leapYear = true;

}

}

//Code for any exceptions to the rule here. (AFAIK none yet, but calendars and rules can change.)

return leapYear;

The code in the isLeapYear function is written for clarity, but it could be reduced to a single line encoding all rules.

If you’ve read this far, thanks. I welcome any feedback and would love to hear if anyone uses this pseud-code.

Was just reading about it in “Celestial Calculations” by J. L. Lawrence. See Chapter 3.

Also, C++11 has good support for dates/times, see https://stackoverflow.com/questions/14218894/number-of-days-between-two-dates-c

]]>if ((day_of_month(start_date) == 31) && (day_of_month(end_date) == 30)) day_of_month(start_date) = 30;

After that the original code should be fine.

]]>Will this work correctly for various leaps? Like dst changes? And changing of dst methods?

]]>If you have 29 days, is that:

1 month 1 day, 1 month, or 4 weeks 1 day? Answer: depends on the month.

Honestly, for the initial example, I think the “correct” solution is don’t use uints and let the answer be “5 months minus a day”.

]]>The solve the problem the easiest, is to first add day, do your calculation, then subtract a day.

I suggest the same approach for the calculator, it will feel the most “natural” to humans

So, add a day to start and end, calculate the difference (no bug fix required)