2017-05-15 20 views
0

Ich habe eine Liste in C#Vergleichen Datetime-Listen C# Linq

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

In Liste:

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

Ich möchte die NR2 finden, ich brauche alles außer der StartToCheck und EndToCheck Bereich.

Zum Beispiel:

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

Offensichtlich mein startToCheck ist in List nr2, ist aber nicht finden.

Ich versuchte

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

Aber funktioniert nicht ... Jede Hilfe, bitte?

Dank

+0

Da nr2 '.End' größer ist als' endToCheck', warum sagst du nr2 ist die richtige Antwort? Suchst du nur nach Überschneidungen? – NetMage

+0

Ja, ich muss alle anderen bekommen –

+0

Ich bin verwirrt ... In Ihrem Beispiel ist Ihr "endToCheck" außerhalb dieser beiden Bereiche, also warum wollen Sie das zweite Element zurückgegeben? Sie haben nicht wirklich erklärt, was Ihre Prüfung tun sollte, nur ein Beispiel gegeben und ein Beispiel definiert kein Problem. Sollte es einen Bereich zurückgeben, der sich mit dem angegebenen Bereich überschneidet?Nur Termine, an denen sich der startToCheck innerhalb des Bereichs befindet und der endToCheck danach ist? Etwas anderes? Sie müssen genau definieren, welches Verhalten Sie wollen und dann können wir erklären, warum Ihr Ansatz nicht funktioniert. – Chris

Antwort

0

Um alle Mitglieder der Liste zu finden, die die startToCheck-endToCheck Bereiche überlappen, genügt es, alle Mitglieder zu finden, die entweder ein enthalten.

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

Nein, tut es nicht. Sie haben den Fall verpasst, in dem 'startToCheck' vor dem Bereich steht und' endToCheck' danach ist. obwohl ich denke, es hängt davon ab, ob Sie nach einer Kreuzung oder nur einer Teilkreuzung suchen. Leider hat das OP uns keine Hinweise gegeben, was sie eigentlich wollen ... :( – Chris

+0

Ich habe den fehlenden Fall hinzugefügt. – NetMage

1

Aus Ihrer Frage (und die anderen Antworten nicht zu sein, was Sie wollen), entnehme ich, dass Sie alle Daten wollen die jede Überlappung mit dem Bereich haben Sie suchen.

Es ist schwer, alle Fälle in eine einfache logische Aussage aufzunehmen. Es ist viel einfacher, wenn Sie es umkehren. Mit anderen Worten, lassen Sie uns nach Daten suchen, die nicht überlappen, und dann die anderen bekommen.

Wie würden wir einen Bereich definieren, der sich nicht überschneidet. Nun, es kann einer von zwei Dingen sein:

  • Es endete bereits, bevor Ihre Suche begann sogar. (passiert zu früh)
  • ODER Es begann erst, nachdem Ihre Suche bereits beendet wurde. (Geschah zu spät)

Diese alle Fälle abdeckt, davon aus, dass das Startdatum nicht größer sein kann als das Enddatum (die Sie bereits überprüft werden sollen!).
So, jetzt invertieren wir die Logik:

  • Es endete nach Ihre Suchperiode begonnen hatte (= nicht geschehen zu früh)
  • UND es begann vor Ihre Suchperiode beendet (= nicht geschehen zu spät)

Wenn es nicht zu früh, und es ist nicht zu spät, dann muss es genau richtig sein.

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

Weitere Erläuterungen

Ich weiß, es ist seltsam Ihre Anreise Datum mit dem Ende der Periode entsprechen und umgekehrt. Aber das macht Sinn. Wenn wir gültige Startdaten betrachten, kann es zwei Möglichkeiten sein:

  • Diejenigen, die in die Periode Sie suchen (startPeriod < myDate.Start < endperiod)
  • Diejenigen gestartet, die vor die Periode begonnen Sie suchen (myDate.Start < startPeriod < endperiod)

Wenn Sie in die Klammern schauen, werden Sie eine unerwartete (aber nicht zu leugnende) Wahrheit sehen: Es spielt keine Rolle, ob myDate.Start vor oder nach startPeriod passiert ist; da entweder könnte korrekt sein.
In beiden Fällen jedoch myDate.Start wird immer kleiner als endperiod sein. Deshalb passen wir myDate.Start zu endperiod.

Wenn myDate.Start nicht kleiner als endPeriod, dann zu spät geschah. Die gleiche Logik gilt für die Betrachtung myDate.End und startperiod. Wenn Sie es aufschreiben, sehen Sie das gleiche Muster.

Hinweis ich nur auf einer der beiden Vergleiche erarbeitet (da sie auf dem gleichen Prinzip arbeiten), aber Sie müssen beide verwenden, wenn Sie korrekt ausgegeben werden soll. Diese können nicht getrennt arbeiten, da beide unvollständige Auswertungen sind (aber zusammen sind sie komplett)