Check if a date range is within a date range
Here's a solution (missing null
argument-validation, and validation within Membership
that EndDate > StartDate
) using Collection<T>
:
public class Membership
{
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; } // If null then it lasts forever
private DateTime NullSafeEndDate { get { return EndDate ?? DateTime.MaxValue; } }
private bool IsFullyAfter(Membership other)
{
return StartDate > other.NullSafeEndDate;
}
public bool Overlaps(Membership other)
{
return !IsFullyAfter(other) && !other.IsFullyAfter(this);
}
}
public class MembershipCollection : Collection<Membership>
{
protected override void InsertItem(int index, Membership member)
{
if(CanAdd(member))
base.InsertItem(index, member);
else throw new ArgumentException("Ranges cannot overlap.");
}
public bool CanAdd(Membership member)
{
return !this.Any(member.Overlaps);
}
}
A condition like this should do the trick:
newItem.StartDate <= range.EndDate && newItem.EndDate.HasValue && newItem.EndDate >= range.StartDate
So if I understand this correctly - you want to make sure date range 2 is not within date range 1?
For example:
startDate1 = 01/01/2011
endDate1 = 01/02/2011
and
startDate2 = 19/01/2011
endDate2 = 10/02/2011
This should be a simple case of:
if ((startDate2 >= startDate1 && startDate2 <= endDate1) ||
(endDate2 >= startDate1 && endDate2 <= endDate1))
Basically, a date range overlaps another if any of its endings are within the other range, or vice versa.
static bool AllowedToAdd(List<Membership> membershipList, Membership newItem)
{
return !membershipList.Any(m =>
(m.StartDate < newItem.StartDate &&
newItem.StartDate < (m.EndDate ?? DateTime.MaxValue))
||
(m.StartDate < (newItem.EndDate ?? DateTime.MaxValue) &&
(newItem.EndDate ?? DateTime.MaxValue) <= (m.EndDate ?? DateTime.MaxValue))
||
(newItem.StartDate < m.StartDate &&
m.StartDate < (newItem.EndDate ?? DateTime.MaxValue))
||
(newItem.StartDate < (m.EndDate ?? DateTime.MaxValue) &&
(m.EndDate ?? DateTime.MaxValue) <= (newItem.EndDate ?? DateTime.MaxValue))
);
}
With the usage:
if (AllowedToAdd(membershipList, newItem))
membershipList.Add(newItem);