Microsoft has just announced that a software error in calculating dates (over leap year) caused a major outage in Windows Azure last week.
Was it really a simple error in judgement working around DateTime.Now.AddYears(1) on a leap year?
What coding practices could have prevented this?
EDIT
As dcstraw pointed out DateTime.Now.AddYears(1) on a leap year does in fact return the correct date in .NET. So it’s not a framework bug, but evidently a bug in Date calculations.
Shameless plug:
Use a better date and time API
The built-in .NET date and time libraries are horribly hard to use properly. They do let you do everything you need, but you can’t express yourself clearly through the type system.
DateTimeis a mess,DateTimeOffsetmay lull you into thinking you’re actually preserving the time zone information when you’re not, andTimeZoneInfodoesn’t force you to think about everything you ought to be considering.None of these provide a nice way of saying “just a time of day” or “just a date”, nor do they make a clear distinction between “local time” and “time in a particular time zone”. And if you want to use a calendar other than the Gregorian one, you need to go through the
Calendarclass the whole time.All of this is why I’m building Noda Time – an alternative date and time library built on a port of the Joda Time “engine” but with a new (and leaner) API on top.
Some points you may want to think about, which are easy to miss if you’re not aware of them:
TimeZoneInfois generally willing to reveal, frankly. (It doesn’t support a time zone whose idea of “standard time” changes over time, or which goes into permanent daylight saving time.)As far as specific development practices:
DateTime.NoworDateTime.UtcNow; it makes it easier (feasible!) to unit test