Don Juan
Don Juan

Reputation: 171

Compare DateTime Lists c# linq

I have a List in C#

List<Dates>
public class Dates
{
    public DateTime Start {get; set;}
    public DateTime End {get; set;}
}

In List:

Start - End

  1. 2014-03-17 09:00:00 - 2014-03-17 10:00:00
  2. 2014-03-17 10:59:59 - 2014-03-17 11:44:59

I will like to found the nr2, i meen everyting except the startToCheck and endToCheck range.

For example:

startToCheck = 2014-03-17 11:00:00
endToCheck = 2014-03-17 12:00:00

Obviously, my startToCheck is in List nr2, but is not find it.

I tried

if (Start <= startToCheck && End >= endToCheck)

But is not working... Any help, please?

Thanks

Upvotes: 0

Views: 1995

Answers (3)

NetMage
NetMage

Reputation: 26917

To find any members of the list that overlap the startToCheck to endToCheck ranges, it suffices to find any members that contain either one.

List<Dates> listOfDateRanges;

var ans = listOfDateRanges.Where(r => (r.Start <= startToCheck && startToCheck < r.End) ||
                                      (r.Start < endToCheck && endToCheck <= r.End) ||
                                      (startToCheck <= r.Start && r.End <= endToCheck));

Upvotes: 1

Flater
Flater

Reputation: 13773

From your question (and the other answers not being what you want), I infer that you want all dates who have any overlap with the range you're looking for.

It's hard to include all cases in a simple logical statement. It is much easier if you invert it. In other words, let's look for dates that do not overlap, and then get the other ones.

How would we define a range that doesn't overlap. Well, it can be one of two things:

  • It already ended before your search period even started. (happened too early)
  • OR It only started after your search period already ended. (happened too late)

This covers all cases, assuming that the startdate can never be bigger than the end date (which you should already be checking!).
So now, we invert the logic:

  • It ended after your search period had started (= did not happen too early)
  • AND it started before your search period ended (= did not happen too late)

If it's not too early, and it's not too late, then it must be just right.

    public class Dates
    {
        public DateTime Start {get; set;}
        public DateTime End {get; set;}
    }

    public List<Dates> FindOverlappingDates(DateTime beginPeriod, DateTime endPeriod)
    {
        var dateList = //fill in the list

        var dateRangesThatOverlap = datelist.Where(date =>
                 date.End > beginPeriod
                  && date.Start < endPeriod)

        return dateRangesThatOverlap.ToList();
    }

Further explanation

I know it's weird to match your Startdate with the end of your period and vice versa. But this makes sense. If we consider valid start dates, there can be two options:

  • Those that started in the period you're looking for (startPeriod < myDate.Start < endperiod)
  • Those that started before the period you're looking for (myDate.Start < startPeriod < endperiod)

If you look in the parentheses, you will see an unexpected (but undeniable) truth: it does not matter whether myDate.Start happened before or after startPeriod; since either could be correct.
However, in both cases, myDate.Start will always be smaller than endperiod. This is why we match myDate.Start to endperiod.

If myDate.Start is not smaller than endPeriod, then it happened too late.

The same logic holds true for considering myDate.End and startperiod. If you write it down, you'll see the same pattern.

Note I only elaborated on one of the two comparisons (since they work on the same principle), but you must use both if you want correct output. These cannot work separately, as both of them are incomplete evaluations (but together, they are complete)

Upvotes: 1

Kevin K.
Kevin K.

Reputation: 1397

Try using the DateTime.Compare method: https://msdn.microsoft.com/en-us/library/system.datetime.compare(v=vs.95).aspx

Upvotes: -1

Related Questions