Reputation: 689
Adding 18 months to two dates (start < end)
changes the order. After the operation start > end
:
var start = new DateTime(2017, 05, 30, 15, 30, 00);
var end = new DateTime(2017, 05, 31, 09, 00, 00);
var newStart = start.AddMonths(18);
var newEnd = end.AddMonths(18);
Console.WriteLine(start < end);
Console.WriteLine(newStart < newEnd);
Console.WriteLine(newStart);
Console.WriteLine(newEnd);
Gives the following output:
True
False
11/30/2018 3:30:00 PM
11/30/2018 9:00:00 AM
Adding a different number of months (for example 17) does not exhibit the same behaviour. Which kind of date irregularity is responsible for this?
https://dotnetfiddle.net/dCthCT
Upvotes: 1
Views: 45
Reputation: 61912
Which kind of date irregularity is responsible for this?
In the western (Roman) calendar, some months have 31 days, some only 30 days (and February is special and has only 28, sometimes 29, days).
In your example, you end up with November which has only 30 days. So starting from May 31, we cannot go to November 31 (non-existent), so the BCL framework chooses November 30 instead. Then starting with May 30, we also get to November 30.
When the date components are the same, we go to the time-of-day. Here your "old" values are chosen such that the relative order swaps when you go to the new values.
I do not think there is any other meaningful way to implement AddMonths(int)
such that your requirement, "the relative order of two new values obtained by applying the same .AddMonths(n)
to two old values, should be the same as the relative order of the old values", is met.
In other words, if you see <
as an inequality (math terms), you cannot apply .AddMonths(n)
to both sides of the <
and get a statement that is equivalent to the old one. As a function, "x
maps to x.AddMonths(n)
" is not monotone.
...
All right, they could have chosen to always prefer midnight of the 1st of the next month in each case where the naïve AddMonths
leads to a non-existent date. (Or chosen that instant minus one tick, see Damien_The_Unbeliever's comment below.) While it would not quite fulfill your wish, it would satisfy a weakly increasing criterion:
IF
x < y
, THENx.AddMonths(n) <= y.AddMonths(n)
(less than or equal)
so that the values never swap, only coincide.
However, Microsoft did not choose that one. Maybe because they felt it was more important that x.AddMonths(n)
has the same time-of-day component as x
. Or maybe they felt their way was the most intuitive or natural?
Upvotes: 2