Leap year problem: Difference between revisions
→See also: Adding Time formatting and storage bugs to the See also section |
→Examples: Adding one more Cat 1 example |
||
Line 25: | Line 25: | ||
SystemTimeToFileTime(&st, &ft); |
SystemTimeToFileTime(&st, &ft); |
||
</syntaxhighlight> |
|||
===C#=== |
|||
The following .NET C# code is an example of a Category 1 leap year bug. It will work properly until <code>dt</code> becomes February 29th. Then, it will attempt to create a February 29th of a common year, which does not exist. The <code>DateTime</code> constructor will throw an <code>ArgumentOutOfRangeException</code>.<ref>{{cite web |last1=Johnson-Pint |first1=Matt |title=.NET / C# - Construction from date parts |url=https://stackoverflow.com/a/57530883/634824 |website=Stack Overflow |accessdate=5 February 2020}}</ref> |
|||
<syntaxhighlight lang="csharp"> |
|||
DateTime dt = DateTime.Now; |
|||
DateTime result = new DateTime(dt.Year + 1, dt.Month, dt.Day); |
|||
</syntaxhighlight> |
</syntaxhighlight> |
||
Revision as of 20:22, 5 February 2020
This article needs additional citations for verification. (December 2012) |
The leap year bug (also known as the leap year problem) is a problem for both digital (computer-related) and non-digital documentation and data storage situations which results from the wrong calculation of which years are leap years, or from manipulating dates without regard to the difference between leap years and common years.
Categories
Leap year bugs typically fall into two impact categories[1]:
- Category 1: Those that lead to error conditions, such as exceptions, error return codes, uninitialized variables, or endless loops
- Category 2: Those that lead to incorrect data, such as off-by-one problems in range queries or aggregation
Examples
Windows C++
The following Windows C++ code is an example of a Category 1 leap year bug. It will work properly until st
becomes February 29th. Then, it will attempt to create a February 29th of a common year, which does not exist. Passing this to any function that accepts a SYSTEMTIME
struct will likely fail.
For example, the SystemTimeToFileTime
call shown here will return an error code. Since that return value is unchecked (which is extremely common), this will result in ft
being left uninitialized.[2]
SYSTEMTIME st;
FILETIME ft;
GetSystemTime(&st);
st.wYear++;
SystemTimeToFileTime(&st, &ft);
C#
The following .NET C# code is an example of a Category 1 leap year bug. It will work properly until dt
becomes February 29th. Then, it will attempt to create a February 29th of a common year, which does not exist. The DateTime
constructor will throw an ArgumentOutOfRangeException
.[3]
DateTime dt = DateTime.Now;
DateTime result = new DateTime(dt.Year + 1, dt.Month, dt.Day);
JavaScript
The following JavaScript code is an example of a Category 2 leap year bug. It will work properly until dt
becomes February 29th, such as on 2020-02-29. Then it will attempt to set the year to 2021. Since 2021-02-29 doesn't exist, the Date
object will roll forward to the next valid date, which is 2020-03-01.[4]
var dt = new Date();
dt.setFullYear(dt.getFullYear() + 1);
C# (and others)
The following C# code is an example of a Category 2 leap year bug. It is also seen in many other languages. It incorrectly assumes that a leap year occurs exactly every four years.[5]
bool isLeapYear = year % 4 == 0;
The correct leap year algorithm is explained at Leap Year Algorithm.
Occurrences
There have been many occurrences of leap year bugs:
- In 2016, a leap year bug in the luggage conveyor system at Düsseldorf Airport on February 29th caused over 1,200 pieces of luggage to miss their flights.[6]
- In 2016, a large number of additional leap year bugs were cataloged at Code of Matt - List of 2016 Leap Day Bugs.
- In 2012, Microsoft Azure was taken offline by the leap year bug on February 28, 2012. At 5:45 PM PST Windows Azure team became aware of an issue, apparently due to a time calculation that was incorrect for the leap year.
- In 2012, Gmail's chat history showed a date of 12/31/69 for all chats saved on February 29, 2012.[citation needed]
- In 2012, TomTom satellite navigation devices malfunctioned due to a leap year bug that first emerged on March 31, 2012.[7]
- Sony's PlayStation 3 incorrectly treated 2010 as a leap year, so the non-existent February 29, 2010 was shown on March 1, 2010, and caused a program error.[8]
- At midnight on December 31, 2008, many[9] first generation Zune 30 models froze.[10][11] Microsoft stated that the problem was caused by the internal clock driver written by Freescale and the way the device handles a leap year. It automatically fixed itself 24 hours later, but an intermediate "fix" for those who did not wish to wait was to drain the device's battery and then recharge after 12 noon UTC on January 1, 2009.[12][13]
- In 1998, two aluminum smelting plants at Tiwai Point, New Zealand, and Bell Bay, Tasmania, Australia, experienced a leap year bug on December 31st, when each of the 660 computers controlling the smelting potlines shut down at the stroke of midnight simultaneously and without warning. The computers were not programmed to handle the 366th day of the year. Repair costs were estimated at more than $1 million NZD.[14]
- Microsoft Excel has, since its earliest versions, incorrectly considered 1900 to be a leap year, and therefore that February 29, 1900 comes between February 28 and March 1 of that year. The bug originated from Lotus 1-2-3, and was purposely implemented in Excel for the purpose of backward compatibility. Microsoft has written an article about this bug, explaining the reasons for treating 1900 as a leap year.[15] This bug has been promoted into a requirement in the Ecma Office Open XML (OOXML) specification.[16][17]
See also
References
- ^ Johnson-Pint, Matt. "What are some examples of leap year bugs?". Stack Overflow. Retrieved 5 February 2020.
- ^ Johnson-Pint, Matt. "Win32 / C++ SYSTEMTIME struct manipulation". Stack Overflow. Retrieved 5 February 2020.
- ^ Johnson-Pint, Matt. ".NET / C# - Construction from date parts". Stack Overflow. Retrieved 5 February 2020.
- ^ Johnson-Pint, Matt. "JavaScript - Adding Year(s)". Stack Overflow. Retrieved 5 February 2020.
- ^ Johnson-Pint, Matt. "Determining if a Year is a Leap Year". Stack Overflow. Retrieved 5 February 2020.
- ^ "Airport hiccup leaves 100s of passengers pantless". The Local (de). Retrieved 5 February 2020.
- ^ "TomTom sat-nav devices hit by GPS 'leap year bug'". BBC News. Retrieved 5 February 2020.
- ^ "Sony fixes PS3 leap year bug". Metro. 2 March 2010. Retrieved 10 October 2019.
- ^ "Home - Microsoft Answers". Forums.zune.net. Archived from the original on August 30, 2009. Retrieved 2011-07-27.
- ^ John Herrman (2008-12-31). "30GB Zunes Failing Everywhere, All At Once". Gizmodo.com. Retrieved 2011-07-27.
- ^ Geere, Duncan. "BREAKING: Zunes worldwide hit by mystery crash : Tech Digest". Techdigest.tv. Retrieved 2011-07-27.
- ^ "Zune 30 FAQ". Microsoft. December 31, 2008. Retrieved January 1, 2009.
- ^ Zadegan, Bryant (January 3, 2009). "A lesson on infinite loops". AeroXperience. Retrieved January 5, 2009.
- ^ Towler, Jim. "Leap-Year software bug gives "Million-dollar glitch"". The RISKS Digest. ACM Committee on Computers and Public Policy. Retrieved 5 February 2020.
- ^ Excel 2000 incorrectly assumes that the year 1900 is a leap year. Retrieved 2013-09-22.
- ^ Standard ECMA-376 / Open Office XML File Formats. Retrieved 2016-09-10.
- ^ ISO/IEC 29500 / Open Office XML File Formats. Retrieved 2016-09-10.