To those that claim "dealing with dates is not easy", a really simple unit test would have caught that bug - like feeding the function integers from 1 to 1000 and testing that it did not crash for any of them. Bonus points for testing that it returned something sensible each time.<p>Sadly, this code probably wasn't unit tested at all.
The lookup table solution in the comments seems sane enough, Always nicer to do lookups than loops.
You could improve on it by pretty much runlength encoding the table. Instead of storing 0,0,0,0 just store the number of 0s, although then you might need to iterate instead of simple lookup which would negate the point of using a lookup.<p>Also seems like most RTC chips I've worked with store the year,date,month as BCD or similar, and deal with the rollovers as they occur, on the chip. Only Storing days since 1980 seems like a lot more work in software.<p>I do think it's quite right to put the blame squarely at MS for this though, a simple code review, or a quick test plan would have picked it up easily.
It all comes down to the fact that dealing with the Gregorian calendar (and time in general) is not easy. And that's because our system is based on the position of the planet in relation to the sun. Let's get on with implementing Metric time already.