January 5, 2009
(From pastie.org)
So, everybody on earth with a 30GB Microsoft Zune MP3 player found themselves in a world of hurt December 31st. The bootup progress meter would get so far, then stop.
while (days > 365)
{
if (IsLeapYear(year))
{
if (days > 366)
{
days -= 366;
year += 1;
}
}
else
{
days -= 365;
year += 1;
}
}
The hitch of course, is that there were 366 days in 2008. Microsoft accounted for this -- or more accurately Freescale did -- but goofed the edge case.
When the year converter got to 12/31/2008 it saw 28 years and 366 days (The Zune uses the "Microsoft epoch" of 1/1/1980) so the while loop stayed in effect. But the check for being a leap year sent it into a different branch of code, and nothing ever got subtracted from the day count. It stayed in [366 > 365] -> [enter loop] -> (effectively a) [nop] forever so the progress bar hung in an infinite loop.
My gut instinct is to change the loop to count while days > 366, then do an if statement for not-leap-year, which would be computationally the same as what they had. At the end you could conceivably have 366 days on the dot, so after the loop you'd need one last not-leap-year check to see if you're on Dec. 31 of a leap year or Jan. 1 right after a not-leap-year. Someone who's spent more than 10 seconds thinking about it may do better though.
And I'm sure some schlub at Freescale told his boss, "oh yeah, I accounted for leap years no problem." I mean, how hard can it be?