Dealing with Leap Years in JavaScript

October 4, 2014, 8:53 pm
Author: James Griffiths

Date handling with JavaScript can be a tricky business to get right, particularly when it comes to calculating leap years. Thankfully, once you understand the principles behind accomplishing this, the task becomes relatively easy...

Play it again Gregorian

Our first approach involves putting together a function that can detect leap years by observing the following 3 Gregorian Calendar rules:

  1. Most years that are divisible by 4 are Leap Years (I.e. 2004, 2008, 2012)
  2. And most years that are divisible by 100 are not Leap Years
  3. Except those that are also divisible by 400 (then they are Leap Years)

With these rules in mind it becomes relatively simple to put together a function that can be used to calculate whether a given date range equates to a Leap Year or not.

For example:

function isDateRangeEqualToLeapYear(year)
{
  return !((year % 4) && (year % 100) || !(year % 400));
}

By using the ! operator we can return a boolean value from the function which indicates whether or not the supplied date range is a Leap Year or not:

isDateRangeEqualToLeapYear(2008);
// true
isDateRangeEqualToLeapYear(2009);
// false
isDateRangeEqualToLeapYear(2010);
// false
isDateRangeEqualToLeapYear(2011);
// false
isDateRangeEqualToLeapYear(2012);
// true
isDateRangeEqualToLeapYear(2013);
// false
isDateRangeEqualToLeapYear(2014);
// false

This method also benefits from being quite fast as no native JavaScript Objects are being created to perform the date manipulation. This speeds up execution times significantly when working with large data sets to process.

The simpler but more costly method

The first approach is robust, efficient and reliable but it's not the only way to detect Leap Years. Instead we could resort to some clever manipulation using the native JavaScript Date object like so:

new Date(2014, 1, 29).getMonth();

What the above snippet does is:

  1. Create a Date object
  2. Pass the current year into the Date object
  3. Followed by the numeric value for the month of February (JavaScript counts months from 0 so January is 0, February is 1, March is 2 etc)
  4. Finally we assign a day value of 29 (as February has 28 days in non-Leap Years and 29 in Leap Years)
  5. Then we use the getMonth() method to return the numeric value of the month detected

If the supplied Year value is a non-Leap Year the script will return a result of 2 (as it treats the numeric value of the day parameter as if the date will belong to March as a result - 28 days in a non-Leap Year February so 29 will roll over into March instead).

However if the supplied year value is that of a Leap Year the script will return a result of 1 which indicates that the month returned is that of February.

For example, if you run the above script in your browser Console you should something akin to the following:

new Date(2012, 1, 29).getMonth();
// 1
new Date(2013, 1, 29).getMonth();
// 2
new Date(2014, 1, 29).getMonth();
// 2


// 1 = February, a Leap Year
// 2 = March, NOT a Leap Year

A much simpler and easier to implement solution to calculating Leap years but the performance overhead is larger due to the creation and use of native JavaScript objects and their associated methods. With most scripts this probably won't be noticeable enough to be a concern but if you're processing large amounts of data (I.e. somewhere north of 10,000 items) then you might want to reconsider the above approach.

And there you have it, 2 different approaches to detecting and handling Leap Years in JavaScript. Not quite as difficult or as challenging as it may first appear but whichever choice suits you best depends on your preferences and performance needs.

Categories

« Return to Posts

Post a comment

All comments are welcome and the rules are simple - be nice and do NOT engage in trolling, spamming, abusiveness or illegal behaviour. If you fail to observe these rules you will be permanently banned from being able to comment.