Ein Datum mit einem anderen vergleichen Java/Eclipse?

4 Antworten

Du hast auch nirgendwo die Variablen year, month und day deklariert, sowohl Time als auch Date enthalten nur hour, minute und second (was wenig Sinn macht). Und dann müsstest du auch bspw. über that.date.year und nicht über that.year darauf zugreifen.


dennisschmitt 
Beitragsersteller
 08.11.2019, 23:27

Danke, wie verweise ich dann auf this.year ? bei that.date.year ist es mir klar und verstehe das auch. Aber wie würde ich das mit this machen?

Blvck  08.11.2019, 23:48
@dennisschmitt

Übrigens ist es ziemlich sinnlos, die Methode für isLaterThan nochmal komplett runterzuschreiben, du kannst auch einfach das machen:

boolean isLaterThan(Time that) {
    return !this.isEarlierThan(that);
}
dennisschmitt 
Beitragsersteller
 08.11.2019, 23:50
@Blvck

Tatsache, wenn ich es jetzt so sehe, dann ist es komplett logisch aber von alleine wäre ich nicht drauf gekommen. Vielen Dank

Warum machst du nicht einfache int-Vergleiche?

Baue in die Klassen Time, Date und DatTime Methoden mit dem Namen toInt() ein. Diese geben die Sekunden innerhalb eines Tages oder die Tage in einem Jahr, gerne auch mit 31 Tagen pro jeden Monat und das Jahr mit 372 (31*12) Tagen oder mehr.

Danach brauchst du nur noch toInt( that ) <= toInt( this ) zu prüfen. Keine If-Kette, die keiner mehr durchblickt.

Time:: toInt() { return 3600 * hour + 60 * minute + second; }

Date:: toInt() { return 372 * year + 31 * month + day; }

DateTime:: toInt() { return 86400 * Date::toInt() + Time::toInt(); }

Der Code soll bespielhaft sein, die Syntax ist anzupassen.


dennisschmitt 
Beitragsersteller
 08.11.2019, 23:54

Das ist auch eine Klasse Möglichkeit, danke sehr das probier ich auch direkt mal aus :D

gogogo  09.11.2019, 10:19
@dennisschmitt

Hinweis: alle Berechnungen beruhen darauf, dass die Werte bei 0 anfangen, auch für den Monat. Sollte der bei 1 anfangen, würde ich die Berechnung sicherheitshalber bei 32 bzw. 12 * 32 laufen lassen.

Zur Veranschaulichung kannst du auch 100 Tage im Monat und 100 Monate im Jahr nehmen.

Dann würde das Datum 09.11.2019 die Zahl 20191109 als Integer ergeben. Faktoren sind dann 100 und 10000 in der Klasse Date

Es tut mir Leid. Aber ich muss mich da mal einklinken und mich zur Codequalität äußern...

Ich weiss, dass man als Anfänger auch relativ schnell Lösungen entwickelt bekommt, die irgendwie funktionieren. Dennoch denke ich, dass man darauf hinweisen sollte, dass der Ansatz mit den if-Kaskaden nicht dem Problem angemessen ist und die Implementation "rigide" und "fragil" macht.

  1. Es sind zu viele Teile anzufassen, falls man etwas ändern muss
  2. Es überlappen die Funktionalitäten von isEarlierThat und isLaterThan, es existiert redundanter Code (wenn etwas nicht früher ist, dann ist es entweder gleich oder später, wobei "später" bei dir separat implemeniert ist)
  3. Es wurde nicht die generelle Struktur erkannt

Date, Time und DateTime besitzen inherent dieselbe Struktur. Sie basieren auf geordneten Elementen, über die immer mit demselben Algorithmus "befeuert" werden können, ohne den Algorithmus selber anfassen zu müssen.

public class Date {

    private static final int INDEX_YEAR = 0;
    private static final int INDEX_MONTH = 1;
    private static final int INDEX_DAY = 2;
    
    private static final Integer INITIAL_DAY = 1;
    private static final Integer INITIAL_MONTH = 1;
    private static final Integer INITIAL_YEAR = 1979;
    
    private Integer[] data = initialData();

    private static Integer[] initialData() {
        
        Integer[] initialData = new Integer[3];
        
        initialData[INDEX_YEAR]  = INITIAL_YEAR;
        initialData[INDEX_MONTH] = INITIAL_MONTH;
        initialData[INDEX_DAY]   = INITIAL_DAY;
        
        return initialData;
    }
    
    public Date(int day, int month, int year) {
        this.data[INDEX_YEAR]  = year;
        this.data[INDEX_MONTH] = month;
        this.data[INDEX_DAY]   = day;
    }
    
    public boolean isEqualTo(Date thatDate) {
        return compare(this, thatDate) == 0;
    }

    public boolean isLaterThan(Date thatDate) {
        return compare(this, thatDate) > 0;
    }

    public boolean isEarlierThan(Date thatDate) {
        return compare(this, thatDate) < 0;
    }

    private int compare(Date thisDate, Date thatDate) {
    
        int compare = 0;
        int index   = 0;
        
        while(compare == 0 && index < data.length) {
            
            int thisElement = thisDate.data[index];
            int thatElement = thatDate.data[index];
            
            compare = thisElement - thatElement;
            
            index++;
            
        }

        return compare;
    }
        
}

Ich habe hier nur einmal "Date" implementiert. "Time" würde komplett identisch aussehen, nur dass sich Namen ändern. Das sollte einen stutzig machen und man sollte nach einer Abstraktion suchen.

Ich möchte dir nur sagen, dass dein Vorgehen für die ersten Schritte ok ist, aber im Nachgang ganz andere Ansätze verfolgt werden müssen, um Rock-Solid-Implementationen zu haben, die diversen Qualitätsansprüchen genügen.

Abgesehen von den Antworten, die du ja jetzt schon bekommen hast...also das mit den ganzen If Abfragen geht ja gar nicht :D.


dennisschmitt 
Beitragsersteller
 08.11.2019, 23:27

Wie würde es besser sein hast du da auch einen Tipp :D

FouLou  08.11.2019, 23:42
@dennisschmitt

Speichere die time z.b. nur als Sekunden. Minuten und Stunden berechnest du in der Klasse.

So reicht dir eine einzige abfrage. Nämlich sind die Sekunden von this kleiner als that.

Das ganze kannste auch für Date machen. Nimmst n Long mit den Tagen seit 1.1.1 und fertig.

Reicht dir auch eine Abfrage auf diesen Wert. Das jüngere Datum hat weniger Tage seit dem Referenz Datum.

Ahnlich wie gogogo das gemacht hätte. (Tipp die Magic Numbers in konstanten verpacken)