'Date Diff By Ignoring Leap Days
Please share some logic to find date difference between two dates which would ignore leap days, c# Subtract method includes the leap days. E.g. for startDat= 26-02-2016 and endDate= 03-03-2016 I want answer to be 5 and not 6. Similarly for any other years.
Thanks!
Solution 1:[1]
One way to do it is the following:
public static int DayDiff(DateTime d1, DateTime d2)
{
DateTime min, max;
if(d1 < d2)
{
min = d1; max = d2;
}
else
{
min = d2; max = d1;
}
int nbOfDays = 0;
while(max.Date != min.Date)
{
min = min.AddDays(1);
if (min.Month != 2 || min.Day != 29) // Skip leap day
nbOfDays++;
}
return nbOfDays;
}
Solution 2:[2]
This is probably the most complicated way of doing this but it survived my test cases and seems to get the job done.
- Calculate the difference in total years
Years
. - Compute the
Days
of the remaining interval. - Check it for a leap day. If there is one, compute
--Days
. - Return
Days + Years * 365
.
/// <summary>
/// Determines the ABSOLUTE difference of FULL years between two dates.
/// Leap days are ignored; the 29th of February is treated as if it was the 28th
/// (conforming with Aventurian calendars).
/// </summary>
/// <param name="Early">The earlier date</param>
/// <param name="Late">The later date</param>
/// <returns>Difference in full years (absolute value >= 0)</returns>
public static int AbsDeltaInYears(DateTime Early, DateTime Late)
{
if (Early > Late) throw new ArgumentException("'Late' must be greater or equal to 'Early'");
// Aventurian calendars do not have leap years: check for Feb, 29th
const int Feb = 2;
const int LeapDay = 29;
if (Early.Day == LeapDay && Early.Month == Feb) Early = Early.AddDays(-1);
if (Late.Day == LeapDay && Late.Month == Feb) Late = Late.AddDays(-1);
int Delta = Late.Year - Early.Year;
// correction if the one year is not a full year
if (Late.Month < Early.Month || (Late.Month == Early.Month && Late.Day < Early.Day))
Delta--;
return Delta;
}
/// <summary>
/// Calculate the difference in days (ignoring leap days which the Aventurian calendar does not have).
/// </summary>
/// <param name="time"></param>
/// <param name="reference"></param>
/// <returns></returns>
public static int DeltaInDays(DateTime time, DateTime reference)
{
// Needed to determine leap years
GregorianCalendar EarthCalendar = new();
DateTime Early = time <= reference ? time : reference;
DateTime Late = time > reference ? time : reference;
int Years = AbsDeltaInYears(Early, Late);
// skip leap days by using whole years
int Days = Years * DaysInYear;
// add remaining interval
DateTime EarlyPlusYears = Early.AddYears(Years);
Days += (Late - EarlyPlusYears).Days;
// One leap day may be left, remove if necessary
if (EarthCalendar.IsLeapYear(EarlyPlusYears.Year) && EarlyPlusYears.DayOfYear < 31 + 29)
Days--;
else
{
if (EarthCalendar.IsLeapYear(Late.Year) && Late.DayOfYear > 31 + 28)
Days--;
}
return Days;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Jan |