/// <summary> /// Compares a Date to another and returns a <c>DateTimeSpan</c>. /// </summary> /// <param name="dateStart">The date start.</param> /// <param name="dateEnd">The date end.</param> /// <returns>A DateTimeSpan with the Years, Months, Days, Hours, Minutes, Seconds and Milliseconds between the dates.</returns> public static DateTimeSpan GetDateTimeSpan(this DateTime dateStart, DateTime dateEnd) => DateTimeSpan.CompareDates(dateStart, dateEnd);
internal static DateTimeSpan CompareDates(DateTime date1, DateTime date2) { if (date2 < date1) { var sub = date1; date1 = date2; date2 = sub; } var current = date1; var years = 0; var months = 0; var days = 0; var phase = Phase.Years; var span = new DateTimeSpan(); var officialDay = current.Day; while (phase != Phase.Done) { switch (phase) { case Phase.Years: if (current.AddYears(years + 1) > date2) { phase = Phase.Months; current = current.AddYears(years); } else { years++; } break; case Phase.Months: if (current.AddMonths(months + 1) > date2) { phase = Phase.Days; current = current.AddMonths(months); if (current.Day < officialDay && officialDay <= DateTime.DaysInMonth(current.Year, current.Month)) { current = current.AddDays(officialDay - current.Day); } } else { months++; } break; case Phase.Days: if (current.AddDays(days + 1) > date2) { current = current.AddDays(days); var timespan = date2 - current; span = new DateTimeSpan( years, months, days, timespan.Hours, timespan.Minutes, timespan.Seconds, timespan.Milliseconds); phase = Phase.Done; } else { days++; } break; } } return(span); }