# Überprüfen von Datums/zeitwerten



## skelle (13. Apr 2010)

Hallo,
ich bastel gerade an einer Funktion um zu überprüfen ob ein Objekt in eine DB eingetragen werden soll.
Die Auswahl erfolgt anhand des Timestamps bzw des Datums/Uhrzeit des Datensatzes.

Szenario:
Ich parse eine LogDatei in Objekte.
Es stehen dann Jahr, Monat, Tag und Stunde des Eintrags zur Verfügung.

Der Tag ist in 5 teile eingeteilt.
21-7
8 - 10 
11 - 13 
14 - 16
17 - 20

Die Objekte sollen eingetragen werden wenn sie in einen Bereich fallen der bereits abgeschlossen ist.

Soll heissen:
Wenn wir den 02.01.10 13:30 haben 
dürfen alle Eintrage bis zum 02.10.10 bis 10:59 eingetragen werden da erst um 14 Uhr ein neuer Bereich beginnt.

Meine aktuelle Lösung erscheint mir etwas unhandlich und ist auch bei Monatswechseln nicht funktionsfähig ^^

```
//Überprüfung ob der Eintrag bereits aufgenommen werden soll
      int dayEntry, dayNow,hourEntry, hourNow;
      SimpleDateFormat sdf = new SimpleDateFormat("yymmddHH");
      Date entry = sdf.parse(date + String.valueOf(time));
      Date now = new Date(System.currentTimeMillis());
      
      SimpleDateFormat dayFormatter = new SimpleDateFormat("dd");
      SimpleDateFormat hourFormatter = new SimpleDateFormat("HH");
      dayEntry = Integer.valueOf(dayFormatter.format(entry));
      dayNow = Integer.valueOf(dayFormatter.format(now));
      hourEntry = Integer.valueOf(hourFormatter.format(entry));
      hourNow = Integer.valueOf(hourFormatter.format(now));
      
      boolean doAdd = false;
      
      if(dayNow > dayEntry && checkEntryTime(hourEntry) != 0)
         doAdd = true;
      if(dayNow == dayEntry && checkEntryTime(hourNow) > checkEntryTime(hourEntry))
         doAdd = true;
      
      if(doAdd)
         this.entrys.add(new LogEntry(date, time, url, action, voId));
```

ich könnte noch einen monthformatter hinzufügen und auch noch darauf prüfen aber das würde die ganze sache noch weiter aufblähen denk ich.

Ich packs aber iwie nich so wirklich eine vernünftige Lösung hier umzusetzen ... auch wenn das Problem jetz nicht so verzwickt ist.

Kann mir wer n Denkanstoss bzw. eine einfachere Lösung für mein Problem geben?

greetz skelle

edit: checkEntrytime gibt mir den Tagesabschnitt zurück in welchem sich die Uhrzeit befindet

```
private int checkEntryTime(int hour)
   {
      if (hour >= 8 && hour < 11)
         return 1;
      if (hour >= 11 && hour < 14)
         return 2;
      if (hour >= 14 && hour < 17)
         return 3;
      if (hour >= 17 && hour < 20)
         return 4;
      if (hour > 20 || hour < 8)
         return 0;
      
      return -1;
   }
```


----------



## JohannisderKaeufer (13. Apr 2010)

Was mir hier ganz spontan einfällt sind die folgenden Interface

Comparator und Comparable.

Das würde ich zumindest benutzen um das ganze einwenig zu Kapseln.

die compareTo() Methode würde dann bei gleichem Zeitraum ein 0 zurückliefern, liegt es in einem vorangegangenen Zeitraum eine negative, sonst eine positive Zahl.


Zudem kann ich mir vorstellen das Zeile 19 zu einem Problem führt.

Wenn es am gleichen Tag einen Eintrag um 5 Uhr gibt und um 21 Uhr verarbeitet werden soll ist erste Bedingung true, die zweite false da (0 > 0) == false.

Zeile 16 ist ebensowenig vertrauenserweckend.
bspl. Eintrag 1.1.2010 21:00
verarbeitung 2.1.2010 1:00
möge korrekt funktionieren.
wird allerdings erst am 3.1.2010 um 1:00 Uhr verarbeitet...

genauso läuft es auch wenn 
Eintrag 1.1.2010 7:00
Verarbeitung 2.1.2010 1:00

um das zu vermeiden sollte mindestens checkEntryTime angepasst werden
time < 8, ergibt 0
time >20, ergibt 5


dayNow > dayEntry, könnte zu  (dayNow - dayEntry) > 1, bzw ==1 werden.

Durch das Nutzen dieser Interface wird das ganze etwas zugänglicher von aussen, so dass man auch JUnit herannehmen könnte um ausgiebig automatisiert zu testen.


----------



## skelle (14. Apr 2010)

danke für die antwort 
dann werd ich mal sehen das ich das ein wenig besser hinbekomme


----------



## kama (14. Apr 2010)

Hi,

habe mir das mal angeschaut....



> Der Tag ist in 5 teile eingeteilt.
> 21-7
> 8 - 10
> 11 - 13
> ...


Ich nehme an, dass damit folgendes gemeint ist (basierend auf der implementierung Deinerseits)..

20:00:00 .... 07:59:59 Uhr  (Bereich 0)
08:00:00 .... 10:59:59 Uhr (Bereich 1)
11:00:00....  13:59:59 Uhr (Bereich 2)
14:00:00 ...  16:59:59 Uhr (Bereich 3)
17:00:00 .... 19:59:59 Uhr (Bereich 4)

danach sieht die checkEntryTime wie folgt aus:


```
public int checkEntryTime(int hour) {
		if (hour >= 8 && hour <= 10) {
			return 1;
		} else if (hour >= 11 && hour <= 13) {
			return 2;
		} else if (hour >= 14 && hour <= 16) {
			return 3;
		} else if (hour >= 17 && hour <= 19) {
			return 4;
		} else {
			return 0;
		}
	}
```

Der Unit Test dazu...

```
@Test
	public void areaTest() {
		Assert.assertEquals(checkEntryTime(0), 0);
		Assert.assertEquals(checkEntryTime(1), 0);
		Assert.assertEquals(checkEntryTime(2), 0);
		Assert.assertEquals(checkEntryTime(3), 0);
		Assert.assertEquals(checkEntryTime(4), 0);
		Assert.assertEquals(checkEntryTime(5), 0);
		Assert.assertEquals(checkEntryTime(6), 0);
		Assert.assertEquals(checkEntryTime(7), 0);

		Assert.assertEquals(checkEntryTime(8), 1);
		Assert.assertEquals(checkEntryTime(9), 1);
		Assert.assertEquals(checkEntryTime(10), 1);

		Assert.assertEquals(checkEntryTime(11), 2);
		Assert.assertEquals(checkEntryTime(12), 2);
		Assert.assertEquals(checkEntryTime(13), 2);

		Assert.assertEquals(checkEntryTime(14), 3);
		Assert.assertEquals(checkEntryTime(15), 3);
		Assert.assertEquals(checkEntryTime(16), 3);

		Assert.assertEquals(checkEntryTime(17), 4);
		Assert.assertEquals(checkEntryTime(18), 4);
		Assert.assertEquals(checkEntryTime(19), 4);
		
		Assert.assertEquals(checkEntryTime(20), 0);
		Assert.assertEquals(checkEntryTime(21), 0);
		Assert.assertEquals(checkEntryTime(22), 0);
		Assert.assertEquals(checkEntryTime(23), 0);

	}
```

und in dem anderen Bereich würde ich das geparste Datum auch in ein Calendar umwandeln...


```
Calendar d = Calendar.getInstance(TimeZone.getDefault(), Locale.GERMANY);
  d.setTime(parsedDate);
		
  Calendar dnow = Calendar.getInstance(TimeZone.getDefault(), Locale.GERMANY);
  dnow.setTime(dateNow);

  int hourNow = dnow.get(Calendar.HOUR_OF_DAY);
  int hour = d.get(Calendar.HOUR_OF_DAY);
		
  int areaNow = checkEntryTime(hourNow);
  int area = checkEntryTime(hour);
```

Weiterhin würde ich die Methode checkEntryTime() umbenennen in z.B. getDayArea() oder so etwas..da die ja nicht nur prüft (check) sondern auch etwas zurück gibt (eben den Bereich)...

Gruß
Karl Heinz Marbaise


----------



## JohannisderKaeufer (14. Apr 2010)

kama hat gesagt.:


> Hi,
> 
> habe mir das mal angeschaut....
> 
> ...



Es geht ihm doch allerdings darum Unterscheiden zu können ob ein Logeintrag in ein davorliegendes Zeitinterval, als dem aktuellen Zeitinterval, fällt oder nicht.

Wenn es momentan 22 Uhr ->0 wäre würde 21 Uhr ->0 in das aktuelle Zeitinterval fallen, 6 Uhr ->0 würde mit dieser implementierung auch in das selbe Zeitinterval fallen, da es sich um den selben Tag handelt und der Rückgabewert von checkEntryTime jeweils bei 0 liegt.

Daher 
0 - 8 -> 0
8 ...  ->1
...
20 - 24 ->5

Also 6 statt 5 Zeitzonen um Zeitzone 0 morgens und 0 abends unterscheiden zu können.


----------

