Это должно сработать. Ключ состоит в том, чтобы уменьшить количество дней на 1, если между заданными двумя датами есть нечетное количество високосных дней.
/// <summary>
/// //Assume DateTime dt1 < DateTime dt2, print out difference between dt1 to dt2 in years, months, weeks and days
/// </summary>
/// <param name="dt1"></param>
/// <param name="dt2"></param>
static void DateDiff(DateTime dt1, DateTime dt2)
{
DateTime zeroTime = new DateTime(1, 1, 1);
int leapDaysInBetween = CountLeapDays(dt1, dt2);
TimeSpan span = dt2 - dt1;
int years = (zeroTime + span).Year - 1;
int months = (zeroTime + span).Month - 1;
int days = (zeroTime + span).Day - (leapDaysInBetween % 2 == 1 ? 1 : 0);
int weeks = days / 7;
int remainingdays = days % 7;
Console.WriteLine(String.Format("\nThe difference between date {0} and date {1} is: \n\t {2} year(s), {3} month(s), and {4} day(s).", dt1, dt2, years, months, days));
Console.WriteLine(String.Format("\nThe difference between date {0} and date {1} is: \n\t {2} year(s), {3} month(s), {4} week(s) and {5} day(s).", dt1, dt2, years, months, weeks, remainingdays));
}
private static int CountLeapDays(DateTime dt1, DateTime dt2)
{
int leapDaysInBetween = 0;
int year1 = dt1.Year, year2 = dt2.Year;
DateTime dateValue;
for (int i = year1; i <= year2; i++)
{
if (DateTime.TryParse("02/29/" + i.ToString(), out dateValue))
{
if (dateValue >= dt1 && dateValue <= dt2)
leapDaysInBetween++;
}
}
return leapDaysInBetween;
}
Провел эти тесты:
static void Main(string[] args)
{
DateDiff(new DateTime(2010, 1, 1), new DateTime(2012, 2, 9));
DateDiff(new DateTime(2010, 1, 1), new DateTime(2012, 4, 9));
DateDiff(new DateTime(2010, 1, 1), new DateTime(2020, 2, 9));
DateDiff(new DateTime(2010, 1, 1), new DateTime(2020, 4, 9));
DateDiff(new DateTime(2020, 2, 29), new DateTime(2021, 2, 28));
DateDiff(new DateTime(2019, 2, 28), new DateTime(2021, 2, 28));
}
Вот распечатки:
Разница между датой 01.01.2010 12:00:00 AM и датой 04.09.2012 12:00:00 AM составляет: 2 года, 3 месяца и 9 дней.
Разница между датой 01.01.2010 12:00:00 AM и датой 04.09.2012 12:00:00 AM составляет: 2 года, 3 месяца, 1 неделя (недели) и 2 дня. (s).
Разница между датой 01.01.2010 12:00:00 AM и датой 09.02.2020 12:00:00 AM составляет: 10 лет, 1 месяц и 9 дней.
Разница между датой 01.01.2010 12:00:00 AM и датой 09.02.2020 12:00:00 AM составляет: 10 лет, 1 месяц, 1 неделя и 2 дня. (s).
Разница между датой 01.01.2010 12:00:00 AM и датой 09.04.2020 12:00:00 AM составляет: 10 лет, 3 месяца и 9 дней.
Разница между датой 01.01.2010 12:00:00 AM и датой 4/9/2020 12:00:00 AM составляет: 10 лет, 3 месяца, 1 неделю и 2 дня. (s).
Разница между датой 29.02.2020 12:00:00 и датой 28.02.2021 12:00:00 AM составляет: 1 год, 0 месяцев и 0 дней.
Разница между датой 29.02.2020 12:00:00 и датой 28.02.2021 12:00:00 AM составляет: 1 год (лет), 0 месяцев (месяцев), 0 недель (недель) и 0 дней. (s).
Разница между датой 28.02.2019 12:00:00 AM и датой 28.02.2021 12:00:00 AM составляет: 2 года, 0 месяцев и 1 день.
Разница между датой 28.02.2019 12:00:00 AM и датой 28.02.2021 12:00:00 AM составляет: 2 года, 0 месяцев, 0 недель и 1 день. (s).
person
Steve Liu
schedule
05.05.2021