Method to determine if data range contains a leap year

Update 1/14/2008: I pulled a Microsoft zune! My leap check was actually off by 1. Corrected algorithm

As I was going through some of code I previously worked on today I came across this method I wrote a while ago. I’m not too sure  if it will help anyone else but I figured I’d throw it up here. Basically I had a need to figure out if a date entered was inside a period of time in the future (in my case specifically 2.5 years and 3.0 years in the future). My original plan was to just check if number of days fit in between 365*2.5  and 365*3 but I realized as rare of a possiblity as it was a potential leap year could have foiled my plans.

So basically I wrote this method for me to be able to calculate if I need to add another day to my range to make sure they weren’t short changed a day because leap year occurred.

I’d love to hear your opinions on this code if there is anything you’d do differently.

/// <summary>
/// Determines if the DateRange contains a leap year.
/// </summary>
/// <param name="startDate">The start date.</param>
/// <param name="endDate">The end date.</param>
/// <returns></returns>
private static bool DateRangeContainsLeapYear(DateTime startDate, DateTime endDate)
{
  if (startDate.Year == endDate.Year)  
    return  DateTime.IsLeapYear(startDate.Year )

  if (startDate > endDate)
    throw new InvalidDataException("startDate must be less than or equal to endDate.");

  //Bounds check Feb will exist either in start of the first time span date
  //or at the end of the last date potentially
  if (startDate.Month < 3 && DateTime.IsLeapYear(startDate.Year))
    return true;
  if ((endDate.Month >= 3 || (endDate.Month == 2 && endDate.Day == 29))
&& DateTime.IsLeapYear(endDate.Year))
    return true;

  //Start year can't be leap year otherwise we're done
  int startYear = startDate.Year + 1;

//Upper bounds will be handled by i < endYear
  int endYear = endDate.Year;

  for (int year = startYear; year < endYear; year++)
  {
    if(!DateTime.IsLeapYear(year)) continue;
    return true;
  }

  return false;
}

Edit: After feedback from Arran Dyer the endDate.Month > 3 check should be endDate.Month >= 3. This prevents the edge case of comparing 2 march dates occurring inside a leap year from errantly returning false .

BloggingContext.ApplicationInstance.CompleteRequest();

Advertisements

11 thoughts on “Method to determine if data range contains a leap year

  1. if ((endDate.Month > 3 || (endDate.Month == 2 && endDate.Day == 29))
    && DateTime.IsLeapYear(endDate.Year))

    in the above condition one change is required which is as follows
    if ((endDate.Month > 2 || (endDate.Month == 2 && endDate.Day == 29))
    && DateTime.IsLeapYear(endDate.Year))

  2. I know this is pretty old, but this algorithm runs into trouble if the startDate and endDate are in the same year. For example: 2008-01-01 to 2008-02-15 will return true.

    For the same year, you basically add a chunk at the top where you combine the start and end month checks.

  3. Too fiddly and does not even work when it is on the same year. How about the following?

    private bool DoesDateRangeContainsLeapYear(DateTime startPeriod, DateTime endPeriod)
    {
    if(DateTime.IsLeapYear(startPeriod.Year))
    {
    var feb29 = new DateTime(startPeriod.Year, 2, 29);
    if((feb29 >= startPeriod) && (feb29 = startPeriod) && (feb29 <= endPeriod))
    return true;
    }

    return false;
    }

  4. The formatting got messed up in the previous post, Hope this time it is better:
    private bool DoesDateRangeContainsLeapYear(DateTime startPeriod, DateTime endPeriod)
    {
    if(DateTime.IsLeapYear(startPeriod.Year))
    {
    var feb29 = new DateTime(startPeriod.Year, 2, 29);

    if((feb29 >= startPeriod) && (feb29 = startPeriod) && (feb29 < endPeriod))

    return true;
    }

    return false;
    }

  5. Somthing is wrong with this site. Messed up my code badly. let me post section by section: First section
    if(DateTime.IsLeapYear(startPeriod.Year))
    {
    var feb29 = new DateTime(startPeriod.Year, 2, 29);
    if((feb29 >= startPeriod) && (feb29 < endPeriod))
    return true;
    }

  6. second section:
    if (DateTime.IsLeapYear(endPeriod.Year))
    {
    var feb29 = new DateTime(endPeriod.Year, 2, 29);
    if ((feb29 >= startPeriod) && (feb29 < endPeriod))
    return true;
    }
    return false;

    • Interesting, you may be correct if the start date is march and end date is march of the same year along with it is a leap year, it appears you would get false.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s