How to calculate number of leap years between two years in C#

26,391

Solution 1

You can count it using analytic approach. A year is a leap year if it can be divided by 4, but can't be divided by 100, except of case when it can be divided by 400. Assuming that you can count such number by following code:

static int LeapYearsBetween(int start, int end)
{
    System.Diagnostics.Debug.Assert(start < end);
    return LeapYearsBefore(end) - LeapYearsBefore(start + 1);
}

static int LeapYearsBefore(int year)
{
    System.Diagnostics.Debug.Assert(year > 0);
    year--;
    return (year / 4) - (year / 100) + (year / 400);
}

Some kind of math magic. It is much effective solution than using LINQ.

Solution 2

You can do it with LINQ simply as bellow:

var leepYears = Enumerable.Range(startYear, endYear - startYear + 1)
                              .Count(x => DateTime.IsLeapYear(x));

Solution 3

This should perform much better for large spans of time:

public int LeapYearsBetween(int year1, int year2)
{
    var y1 = new DateTime(year1, 1, 1);
    var y2 = new DateTime(year2, 1, 1);
    var nonLeapDays = 365 * (y2.Year - y1.Year);
    var leapDays = (y2 - y1).Days - nonLeapDays;
    return leapDays;
}

Note that this counts the earlier year if it is a leap year, but not the later year. You'll need to modify the function if you need different behavior.

Solution 4

Another Linq :-)

int start = 1980;
int end = 2000;
var count = Enumerable.Range(start, end - start + 1)
                      .Aggregate(0, (a, b) => DateTime.IsLeapYear(b) ? a + 1 : a);

Solution 5

Just another code with primitives types

    public static int CountLeapYears(int startYear, int endYear) 
    {
        int acc = 0;

        while (true)
        {
            if ((startYear % 4 == 0 && startYear % 100 != 0) || startYear % 400 == 0)
                acc++;
            if (startYear + 1 == endYear) break;
            startYear++;
        }

        return acc;
    }
Share:
26,391
Vlad Bezden
Author by

Vlad Bezden

Software engineer with more than 30 years of experience. I specialized in developing highly scalable and high-performance systems. Polyglot: JavaScript, Python, Java, Go, Java, C, C++, C#.

Updated on February 26, 2020

Comments

  • Vlad Bezden
    Vlad Bezden about 4 years

    Is there a better way to calculate number of leap years between two years. Assuming I have start date and end date.

    I have my code, but I think there should be more elegant way.

    calling code:

    var numberOfLeapYears = NumberOfLeapYears(startDate.Year + 1, endDate.Year - 1);
    

    function itself:

        private static int NumberOfLeapYears(int startYear, int endYear)
        {
            var counter = 0;
    
            for (var year = startYear; year <= endYear; year++)
                counter += DateTime.IsLeapYear(year) ? 1 : 0;
    
            return counter;
        }
    

    So if I have startDate = "10/16/2006" and endDate = "4/18/2004" I should only have 1 leap year (2000) in result. Another words startDate's Year and endDate's year should not be calculated, only years in between.

    Thanks in advance for your help.