
From: "Powell, Gary" <powellg@amazon.com>
From: Rob Stewart
Ummm, OK, you made it work, but why? Why would you want to be able to call add_month() on a date and have it always represent the day before the last day of the month?
date d = August 30;
// add six months. add_month(d); // September 30; add_month(d); // October 31?
October 30
add_month(d); // November 30 add_month(d); // December 31?
December 30
add_month(d); // January 30 add_month(d); // February 28/29
According to my scheme: March 1/2
add_month(d); // March 28? 29? 30? 31?
According to my scheme: April 1/2
Just looking this there is no way to predict which day of the month the last call is going to be. I'd find
So? You'd have to know whether you were passing over February in a leap year anyway, which adds variability. Neither scheme is far from August 30 + 7 * 30 days. (According to my quick check, August 30 + 7 * 30 days would be March 29/30.) Now, with add_month(d, 7), where d is August 30, the result would easily be March 30 (add 7 to the month, advancing the year if needed; if the starting day of the month (30) is not in the target month, fall back to adding 7 * 30 days). Since you're adding an irregular value, these differences shouldn't be surprising in the least. Now, if there was a next_month() function, I'd expect this progression: date d = August 30; next_month(d); // September 30 next_month(d); // October 30 next_month(d); // November 30 next_month(d); // December 30 next_month(d); // January 30 next_month(d); // February 28/29 next_month(d); // March 28/29 and: date d = August 30; next_month(d, 7); // March 30 Curiously, though, no one has mentioned "next month" as in the same day of the same week of next month, or the same ordinal day of the week of next month. You could say that these are much more specialized, and don't need to be handled by the library, but think about regular first Monday of the month meetings or other similar scheduling needs. Don't those deserve some attention? Isn't what you've been asking of add_month() really just a case of this broader functionality? That is, you want next_month(d, n, same_day_of_month_or_fall_back), but others may want next_month(d, n, same_ordinal_day_of_week), etc.
it surprising that
(d + year) != (12 * months) + d;
Actually, that expression should easily be an equality. Adding 12 * months to a date should mean to increment the month by 12 and the year by one and that should do the same thing as adding a year to the date.
I think you are looking for a simplistic function for a complex problem. IMO its a trap for the unwary and should be called out as such.
Why is my notion of add_month() "simplistic" and why isn't yours?
I can see the need for LAST, but my contention is that its not enough information to do the least surprising thing.
I don't understand why not. I can understand wanting to get the last day of each month as you increment from month to month, but I can't understand needing the second to last day or third to last day, etc., for any but the oddest situations. LAST seems like a valuable concept if we don't get the more general next_month(d, n, last_day_of_month), next_month(d, n, second_to_last_day_of_month), etc.
The easiest way to resolve this is to either write a FAQ, and or have a dumb rounding month adding function that can screw up the dates for those times when "meet you next month" is the right answer.
I can see how you'd think that, given that you want your preferred behavior to be the "dumb rounding" scheme in the library. At the very least, I think there should be a distinction between add_month() and next_month(). Whether the library ever provides for more complicated schemes is another matter. (A more general mechanism that applies a rule for finding the right day of the new month could be abstracted behind the names "add_month" and "next_month.") -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;