How to calculate number of leap years between two years in C#
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;
}
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, 2020Comments
-
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"
andendDate = "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.