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);

Tags:

C#