1651 Stimmen

Bestimmen Sie, ob sich zwei Datumsbereiche überschneiden.

Angenommen, wir haben Bereiche, die durch DateTime-Variablen StartDate1 bis EndDate1 und StartDate2 bis EndDate2 bezeichnet sind.

3 Stimmen

1 Stimmen

@CharlesBretana Vielen Dank dafür, du hast Recht - das ist fast wie eine zweidimensionale Version meiner Frage!

2 Stimmen

9voto

Bob Punkte 93584

Ich würde dies tun

StartDate1.IsBetween(StartDate2, EndDate2) || EndDate1.IsBetween(StartDate2, EndDate2)

Wo IsBetween so etwas wie

    public static bool IsBetween(this DateTime value, DateTime left, DateTime right) {
        return (value > left && value < right) || (value < left && value > right);
    }

0 Stimmen

Ich würde (left < value && value < right) || (right < value && value < left) für diese Methode bevorzugen.

0 Stimmen

Vielen Dank dafür. Vereinfacht die Dinge in meinem Kopf.

1 Stimmen

Warum würdest du vier Bedingungen überprüfen, wenn du nur zwei überprüfen musst? Scheitern.

8voto

on_ Punkte 536

Die hier veröffentlichte Lösung funktionierte nicht für alle überlappenden Bereiche...

\----------------------|-------A-------|----------------------
    |----B1----|
           |----B2----|
               |----B3----|
               |----------B4----------|
               |----------------B5----------------|
                      |----B6----|
----------------------|-------A-------|----------------------
                      |------B7-------|
                      |----------B8-----------|
                         |----B9----|
                         |----B10-----|
                         |--------B11--------|
                                      |----B12----|
                                         |----B13----|
----------------------|-------A-------|----------------------

Meine Lösung war:

AND (
  ('start\_date' BETWEEN STARTDATE AND ENDDATE) -- berücksichtigt innere und äußere Startdaten
  OR
  ('end\_date' BETWEEN STARTDATE AND ENDDATE) -- berücksichtigt innere und äußere Enddaten
  OR
  (STARTDATE BETWEEN 'start\_date' AND 'end\_date') -- nur für äußere Bereiche nötig, in denen die Daten drin liegen.
)

6voto

a_horse_with_no_name Punkte 489934

Da es mehrere Antworten für verschiedene Sprachen und Umgebungen gab, hier ist eine für standard ANSI SQL.

In Standard-SQL ist es so einfach wie

(StartDate1, EndDate1) überschneidet sich (StartDate2, EndDate2)

vorausgesetzt, alle vier Spalten sind DATE oder TIMESTAMP Spalten. Es gibt true zurück, wenn beide Bereiche mindestens einen Tag gemeinsam haben (unter der Annahme von DATE Werten)

(Nicht alle DBMS-Produkte unterstützen das)


In PostgreSQL ist es auch einfach, die Einbeziehung zu testen, indem man Datumsbereiche verwendet

daterange(StartDate1, EndDate1) @> daterange(StartDate2, EndDate2)

das obige gibt true zurück, wenn der zweite Bereich vollständig im ersten enthalten ist (was sich von "überschneiden" unterscheidet)

5voto

user2314737 Punkte 23784

Dies ist eine Erweiterung der ausgezeichneten Antwort von @charles-bretana.

Die Antwort macht jedoch keinen Unterschied zwischen offenen, geschlossenen und halboffenen (oder halbgeschlossenen) Intervallen.

Fall 1: A, B sind geschlossene Intervalle

A = [StartA, EndA]
B = [StartB, EndB]

                         [---- DateRange A ------]   (True, wenn StartA > EndB)
[--- Date Range B -----]                           

[---- DateRange A -----]                             (True, wenn EndA < StartB)
                         [--- Date Range B ----]

Überschneidung, wenn: (StartA <= EndB) und (EndA >= StartB)

Fall 2: A, B sind offene Intervalle

A = (StartA, EndA)
B = (StartB, EndB)

                         (---- DateRange A ------)   (True, wenn StartA >= EndB)
(--- Date Range B -----)                           

(---- DateRange A -----)                             (True, wenn EndA <= StartB)
                         (--- Date Range B ----)

Überschneidung, wenn: (StartA < EndB) und (EndA > StartB)

Fall 3: A, B rechts offen

A = [StartA, EndA)
B = [StartB, EndB)

                         [---- DateRange A ------)   (True, wenn StartA >= EndB) 
[--- Date Range B -----)                           

[---- DateRange A -----)                             (True, wenn EndA <= StartB)
                         [--- Date Range B ----)

Überschneidungsbedingung: (StartA < EndB) und (EndA > StartB)

Fall 4: A, B links offen

A = (StartA, EndA]
B = (StartB, EndB]

                         (---- DateRange A ------]   (True, wenn StartA >= EndB)
(--- Date Range B -----]                           

(---- DateRange A -----]                             (True, wenn EndA <= StartB)
                         (--- Date Range B ----]

Überschneidungsbedingung: (StartA < EndB) und (EndA > StartB)

Fall 5: A rechts offen, B geschlossen

A = [StartA, EndA)
B = [StartB, EndB]

                         [---- DateRange A ------)    (True, wenn StartA > EndB)
[--- Date Range B -----]                           

[---- DateRange A -----)                              (True, wenn EndA <= StartB)  
                         [--- Date Range B ----]

Überschneidungsbedingung: (StartA <= EndB) und (EndA > StartB)

usw...

Zuletzt ist die allgemeine Bedingung für zwei Intervalle, sich zu überschneiden,

(StartA < EndB) und (EndA > StartB)

wobei eine strenge Ungleichung in eine nicht strenge umwandelt, wann immer der Vergleich zwischen zwei eingeschlossenen Endpunkten gemacht wird.

0 Stimmen

Fälle zwei, drei und vier haben dieselbe Überlappungsbedingung, ist das beabsichtigt?

0 Stimmen

@Marie, ich habe nur einige Fälle aufgelistet (nicht alle)

0 Stimmen

Dies, aber so ausführlich wie Jonathans Lefflers Antwort wäre das, was ich als akzeptierte Antwort auf die Frage des OPs im Sinn hatte.

4voto

Nitin Jadhav Punkte 5051

Kurze Antwort mithilfe von momentjs:

function isOverlapping(startDate1, endDate1, startDate2, endDate2){ 
    return moment(startDate1).isSameOrBefore(endDate2) && 
    moment(startDate2).isSameOrBefore(endDate1);
}

Die Antwort basiert auf den obigen Antworten, ist aber verkürzt.

0 Stimmen

Wenn die beiden Datumsbereiche benachbart sind, wird dies als überlappend gemeldet. (mit anderen Worten, wenn dateRange1 endet, wenn dateRange2 beginnt, überschneiden sie sich nicht - aber diese Funktion würde sagen, dass sie es tun.)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X