No need to worry about leap days or anything. The framework takes a date/time such as 2012-02-29 15:00 and calculates that one year later is 2013-02-28 15:00. Similarly, 2012-01-31 15:00 called with .AddMonths(1) returns 2012-02-29 15:00 and calling that with .AddMonths(-1) returns 2012-01-29 15:00.
As long as you understand how your library handles these calculations, trying to do it manually is likely to get you in trouble.
A gotcha to look out for in .NET's implementation is that because the library is adjusting invalid results down to the last day of the month, addition and subtraction operations are not commutative:
new DateTime(2012, 3, 31)
.AddMonths(-1)
.AddMonths(1) ==> 2012-03-29
new DateTime(2012, 3, 31)
.AddMonths(1)
.AddMonths(-1) ==> 2012-03-30
Right, which is why an understanding of how .NET handles the calculations is important. If it's important that you preserve things like "last day of the month" there are libraries[0] which support this and will do date calculations accordingly.
Comments
In C#:
No need to worry about leap days or anything. The framework takes a date/time such as 2012-02-29 15:00 and calculates that one year later is 2013-02-28 15:00. Similarly, 2012-01-31 15:00 called with .AddMonths(1) returns 2012-02-29 15:00 and calling that with .AddMonths(-1) returns 2012-01-29 15:00.As long as you understand how your library handles these calculations, trying to do it manually is likely to get you in trouble.
A gotcha to look out for in .NET's implementation is that because the library is adjusting invalid results down to the last day of the month, addition and subtraction operations are not commutative:
Right, which is why an understanding of how .NET handles the calculations is important. If it's important that you preserve things like "last day of the month" there are libraries[0] which support this and will do date calculations accordingly.
[0] For example: http://sourceforge.net/projects/dday-ical/