Many of us learned about five years ago that calculating dates in programs actually is a 'big deal'. As the year 2000 approached, forecasts of Y2K costs ranged from $600 billion to $1.5 trillion. The actual cost ended up being about $150 billion. So much for forecasts.
This year, we're being treated to another extra day to catch up on our projects because it's a Leap Year again! Since every program that had been written since Lady Lovelace put quill pen to a coding sheet was put under a microscope just a few years ago, there probably won't be many problems. But in case you were one of the unlucky ones, here's everything you are likely to need to know about calculating leap year information.
The mean time for one year is about 365.2422 days. And therein lies a problem that has plagued civilization since nomadic hunters decided that getting kicked in the cookies by wild animals wasn't nearly as much fun as watching crops grow. How do you create a calendar that stays in sync with the seasons when one year is just slightly more than 365 days long?
Through the centuries, people have created several different ways of adjusting the calendar to solve this problem. The current idea is called, "The Gregorian calendar" and it's pretty good, but even this method is going to need some kind of adjustment in a few thousand years.
If you ever need to calculate dates far into the past, keep these fundamental shifts in mind. (Let me gratefully acknowledge the contribution of calendricist extraordinaire Peter Zilahy Ingerman. All the mistakes are mine. Anything you like is his.) The first calendar that did a reasonable job of keeping up with the seasons, called the Julian calendar, became official in 46 B.C. It replaced a calendar based on lunar cycles. A calendar with a uniform 365 days per year results in an error of almost 6 hours per year. After 100 years, you find yourself more than 24 days ahead of the seasons. The Julian calendar corrects most of the problem because it provides for a leap year with an extra day every four years, or an average of 365.25 days per year. This cuts the error to 11 minutes per year. But by 1582 A.D., the Julian calendar had become out of step with the seasons by 10 days, partly because the extra day wasn't added consistently. If you wonder as I did why the sum of the errors don't appear to add up to the total adjustments that have been made, this is most of the reason.
In October 1582, Pope Gregory XIII ordered that ten days be subtracted from the calendar and came up with the calculation that is used today. To get the Gregorian leap year, simply do not include a leap day in a year divisible by 100 but not divisible by 400. Click Here to view a flow chart that shows how this works. Click the "Back" button in your browser to return.
For those countries that were part of it, including the American colonies, the modern leap year calculation was placed into law by an act of the British Parliament, the Calendar Act 1751. By that time, things had become so out of whack that another 11 days had to be dropped. The day after 2 September 1752 was 14 September 1752.
As many of us learned during the infamous Y2K computing crisis, the year 2000 was the first time some whole countries had to apply the third rule, that every fourth century (1600, 2000, 2400) divisible by 100 is a leap year.
A simple program module to calculate whether a year integer is a leap year can be coded as shown below. Although the code below is left justified, you can copy and paste this into a VB Editor to see it displayed correctly.
Public Function blnLeapYear( _
intYear As Integer) As Boolean
blnLeapYear = False
If intYear Mod 4 = 0 Then
blnLeapYear = True
If intYear Mod 100 = 0 Then
If (intYear Mod 400) _
Then blnLeapYear = False
Or ... just let Visual Basic do all the work for you. Just check to see whether the 29th of February exists in a particular year.
Public Function blnLeapYear(intYear As Integer) _
As Boolean blnLeapYear = IsDate("2/29/" & intYear)
For a side channel issue related to dates, check out the next page is about what programmers misname "Julian" dates.