# Zeiträume vergleichen



## Keo (24. Jul 2009)

Ich habe zwei Zeiträume als Date-Objekte:


```
Date von1, bis1, von2, bis2
```

Ich würde gerne abfragen, ob sich Zeitraum1 (von1-bis1) mit Zeitraum2 (von2-bis2) überschneidet.

Hat jmd einen sauberen Code für mich?


----------



## faetzminator (24. Jul 2009)

```
if ((von2.before(von1) && von1.before(bis2))
        || (von2.before(bis1) && bis1.before(bis2))
        || (von1.before(von2) && bis2.before(bis1))) {
    [...]
}
```
(ungeprüft)

EDIT: before() ist natürlich kürzer


----------



## bygones (24. Jul 2009)

```
if (von1.before(bis2) && von2.before(bis1)) { ... }
```

unter der annahme von1 != bis2 etc


----------



## Spacerat (24. Jul 2009)

müsste so funktionieren:
	
	
	
	





```
boolean ueberschneidung = bis1.compareTo(von2) < 0
                       || bis2.compareTo(von1) < 0;
```
Zur Not kann man "<" auch noch durch "<=" ersetzen.


----------



## MrWhy (24. Jul 2009)

Hi,

Lösungsvorschlag Nr.1 : versuch es doch mal mit der Umrechnung in den julianischen Kalender mit dem kannst du dann Rechnen.

Lösungsvorschlag Nr.2 : Versuch es doch mal mit der Umrechnung in einen UTS damit kann man dann auch rechnen.

Lösungsvorschlag Nr.3 : Falls du eine DB wie MySQL verwendest, mach es mit dieser.

Lösungsvorschlag Nr.4 : siehe die oberen Lösungen 

Grüße

Mr.


----------



## Keo (24. Jul 2009)

Spacerat hat gesagt.:


> müsste so funktionieren:
> 
> 
> 
> ...




danke schön, ich mach dann mal copy-paste


----------



## faetzminator (24. Jul 2009)

Aber es gibt doch im ganzen 3 Cases...:
1. von1 liegt zwischen von2 und bis2
2. bis1 liegt zwischen von2 und bis2
3. von1 ist vor von2 und bis1 ist nach bis2
Und Spacerat's Lösung checkt nur Punkt 1.


----------



## bygones (24. Jul 2009)

faetzminator hat gesagt.:


> Aber es gibt doch im ganzen 3 Cases...:
> 1. von1 liegt zwischen von2 und bis2
> 2. bis1 liegt zwischen von2 und bis2
> 3. von1 ist vor von2 und bis1 ist nach bis2
> Und Spacerat's Lösung checkt nur Punkt 1.


es gibt in der hinsicht viele faelle - aber alle kann man subsummieren auf den von spacerat bzw mein bsp.

siehe auch Test If Date Ranges Overlap


----------



## faetzminator (24. Jul 2009)

interessant:rtfm:


----------



## bygones (24. Jul 2009)

faetzminator hat gesagt.:


> interessant:rtfm:



wobei spacerats falsch ist !

```
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.MONTH, 2); // maerz 2009
Date von1 = calendar.getTime();
calendar.set(Calendar.MONTH, 11); // dezember 2009
Date bis2 = calendar.getTime();
calendar.set(Calendar.MONTH, 8); // September 2009
Date bis1 = calendar.getTime();
Date von2 = new Date(); // Juli 2009

boolean ueberschneidung = bis1.compareTo(von2) < 0 || bis2.compareTo(von1) < 0;
System.out.println(ueberschneidung); false
System.out.println(von1.before(bis2) && von2.before(bis1)); // true
```
er hat die negierung bei seinem Ausdruck vergessen...

```
!(bis1.compareTo(von2) < 0 || bis2.compareTo(von1) < 0)
```


----------



## Spacerat (24. Jul 2009)

@deathbyaclown: ... hast ja recht... aber warum negieren? aus "<" wird ">"... oder etwa doch nicht? Bin mir plötzlich gar nicht mehr so sicher...


----------



## bygones (24. Jul 2009)

Spacerat hat gesagt.:


> @deathbyaclown: ... hast ja recht... aber warum negieren? aus "<" wird ">"... oder etwa doch nicht? Bin mir plötzlich gar nicht mehr so sicher...


siehe link


----------



## sliwalker (24. Jul 2009)

Du kannst auch folgendes machen, denn mit before und after bekommst Du irgendwann einen Knoten im Kopf:

Schreib Dir eine neue Date-Klasse.
Die Klasse hat einen Index und den Datumswert.
Überschreibe compareTo und equals.
Packe alle Deine neuen Datumsobjekte in eine List.
Sortiere die Liste.
Iteriere durch alle Einträge und gucke ob der Index mit dem Schleifenzähler übereinstimmt.

Wenn ja, liegen alle Datumswerte hintereinander.
Wenn nein, überlappen sie sich.


----------



## faetzminator (24. Jul 2009)

sliwalker, deine Idee ist gut, aber was ist, wenn Zeitfenster 1 nach Zeitfenster 2 kommen darf? Oder wenn die End- bzw. Startdaten aufeinander liegen dürfen? Na gut, da kann man den Index als zweiten Vergleichswert verwenden. Umgekehrt ebenfalls (falls keine Treffer erlaubt sind), einfach andersrum.


----------



## sliwalker (24. Jul 2009)

Danke.

Ich habe diesen Weg gerade aus einem anderen UseCase gerissen. Funktioniert aber dennoch (genau wie Du es beschrieben hast). Den Weg nehme ich, wenn ich aus einem Haufen von Datumswerten Perioden ermitteln möchte.

Wenn man es ganz richtig machen will, muss man die Liste von Datumswerte noch ein wenig normalisieren. Doppelte rauswerfen usw...

Aber im Prinzip sollte das auch für diesen Anwendungsfall funktionieren. Man muss halt die compareTo vernünftig anpassen.


----------



## bygones (24. Jul 2009)

sliwalker hat gesagt.:


> Du kannst auch folgendes machen, denn mit before und after bekommst Du irgendwann einen Knoten im Kopf:
> 
> Schreib Dir eine neue Date-Klasse.
> Die Klasse hat einen Index und den Datumswert.
> ...



warum eine komplexere neue lösung erschaffen die mögl. fehler hat wenn es etwas simples für die Lösung schon gibt ?!


----------



## sliwalker (24. Jul 2009)

simpel?
komplex?

wenn du meinst...
Ich halte before und after für wesentlich komplexer, aber egal


----------



## Ebenius (24. Jul 2009)

Spacerat hat gesagt.:


> aus "<" wird ">"... oder etwa doch nicht?


Doch eher so, oder? 
	
	
	
	





```
¬(A < B) ≍ (A ≥ B)
```

Ebenius


----------



## bygones (25. Jul 2009)

sliwalker hat gesagt.:


> simpel?
> komplex?
> 
> wenn du meinst...
> Ich halte before und after für wesentlich komplexer, aber egal


mhm lass mal überlegen... entweder ich schreib n einzeiler mit before bzw compareTo oder ich schreib eine eigene Klasse, überschreib methoden, erstelle eine liste, lasse sie sortieren, iteriere und muss dann richtig vergleichen....

was ist nun komplexer ?


----------



## sliwalker (25. Jul 2009)

Also ich habe mir nur Deinen Link angeschaut und wurde erschlagen von mehreren DIN A4 Seiten an Hinweisen und Vorgehensweisen. Deinen Einzeiler habe ich nicht überprüft.

Aber im Hinblick auf Wiederverwendbarkeit, kann man sich doch wohl einmal die Arbeit machen oder nicht?


----------



## Spacerat (25. Jul 2009)

Ok... Ich hab's verzockt. Mit dem KSKB von deathbyaclown ergab sich folgendes:
	
	
	
	





```
import java.util.Calendar;
import java.util.Date;

public class Overlap
{
  public static void main(String ... args)
  {
    Calendar calendar = Calendar.getInstance();

    // Ueberschneidung
    calendar.set(Calendar.MONTH, 2); // maerz 2009
    Date von1 = calendar.getTime();
    calendar.set(Calendar.MONTH, 8); // September 2009
    Date bis1 = calendar.getTime();
    Date von2 = new Date(); // Juli 2009
    calendar.set(Calendar.MONTH, 11); // dezember 2009
    Date bis2 = calendar.getTime();

    boolean ueberschneidung = bis1.compareTo(von2) > 0 || bis2.compareTo(von1) < 0;
    System.out.println(ueberschneidung);
    System.out.println(von1.before(bis2) && von2.before(bis1));

    // keine Ueberschneidung
    calendar.set(Calendar.MONTH, 2); // maerz 2009
    von1 = calendar.getTime();
    calendar.set(Calendar.MONTH, 5); // Mai 2009
    bis1 = calendar.getTime();
    von2 = new Date(); // Juli 2009
    calendar.set(Calendar.MONTH, 11); // dezember 2009
    bis2 = calendar.getTime();

    ueberschneidung = bis1.compareTo(von2) > 0 || bis2.compareTo(von1) < 0;
    System.out.println(ueberschneidung); // false
    System.out.println(von1.before(bis2) && von2.before(bis1));

    // Abschnitt 2 in Abschnitt 1 (Überschneidung)
    calendar.set(Calendar.MONTH, 2); // maerz 2009
    von1 = calendar.getTime();
    calendar.set(Calendar.MONTH, 11); // Dezember 2009
    bis1 = calendar.getTime();
    von2 = new Date(); // Juli 2009
    calendar.set(Calendar.MONTH, 7); // August 2009
    bis2 = calendar.getTime();

    ueberschneidung = bis1.compareTo(von2) > 0 || bis2.compareTo(von1) < 0;
    System.out.println(ueberschneidung);
    System.out.println(von1.before(bis2) && von2.before(bis1));

    // Abschnitt 1 in Abschnitt 2 (Überschneidung)
    calendar.set(Calendar.MONTH, 2); // maerz 2009
    von2 = calendar.getTime();
    calendar.set(Calendar.MONTH, 11); // Dezember 2009
    bis2 = calendar.getTime();
    von1 = new Date(); // Juli 2009
    calendar.set(Calendar.MONTH, 7); // August 2009
    bis1 = calendar.getTime();

    ueberschneidung = bis1.compareTo(von2) > 0 || bis2.compareTo(von1) < 0;
    System.out.println(ueberschneidung);
    System.out.println(von1.before(bis2) && von2.before(bis1));
  }
}
```
Ausgabe:
	
	
	
	





```
true
true
false
false
true
true
true
true
```
Fazit:
	
	
	
	





```
von1.before(bis2) && von2.before(bis1)
```
und
	
	
	
	





```
bis1.compareTo(von2) > 0 || bis2.compareTo(von1) < 0
```
verhalten sich gleich, wobei ersteres noch ein wenig kürzer und damit 1. übersichtlicher und 2. weniger komplex ist als alles andere (neue Klasse... :lol.
@Ebenius: mit deiner Formel(?) kann ich irgendwie nichts anfangen... für mich liest sich das wie "komischer Haken(A<B)Quadrat(A>=B)". Ok der "komische Haken" könnte eine negation bedeuten. Aber was bedeutet das Quadrat?


----------



## Ebenius (25. Jul 2009)

Spacerat hat gesagt.:


> @Ebenius: mit deiner Formel(?) kann ich irgendwie nichts anfangen... für mich liest sich das wie "komischer Haken(A<B)Quadrat(A>=B)". Ok der "komische Haken" könnte eine negation bedeuten. Aber was bedeutet das Quadrat?


Der Haken ist die logische Negation. Und das Quadrat sagt, dass Du das Unicode-Zeichen für "equivalent to" nicht in Deinem Font hast: 
	

	
	
		
		

		
			





Ebenius


----------



## bygones (26. Jul 2009)

sliwalker hat gesagt.:


> Also ich habe mir nur Deinen Link angeschaut und wurde erschlagen von mehreren DIN A4 Seiten an Hinweisen und Vorgehensweisen. Deinen Einzeiler habe ich nicht überprüft.
> 
> Aber im Hinblick auf Wiederverwendbarkeit, kann man sich doch wohl einmal die Arbeit machen oder nicht?



der link war nur ergänzung - mein einzeiler (und spacerats) sind das was ich eigentlich mein.
Aber auch auf hinblickder wiederverwendbarkeit - warum sich arbeit machen wenn es eben schon existierende Mechanismen gibt ?!


----------

