if-Abfragen bringen mich zum VERZWEIFELN!

Status
Nicht offen für weitere Antworten.

Souljacker

Mitglied
Hallo!

Ich muss ein Programm mit Kalenderfunktionen schreiben. Ich habe folgendes Problem:

Ich möchte überprüfen ob das eingegebene Datum auch gültig ist.

Mein Codefragment welches dies bewerkstelligen soll sieht wie folgt aus:
Code:
boolean isValidDate(int day, int month, int year) {

        // Müsste passen...
        if ((year == 1582) && (month == 10)) {
            if ((day == 5) || (day == 6) || (day == 7) || (day == 8)
                    || (day == 9) || (day == 10) || (day == 11) || (day == 12)
                    || (day == 13) || (day == 14)) {
                return false;
            }
        }

        // Müsste ebenfalls passen
        if ((day < 1) || (month > 12) || (month < 1) || (year < 1)) {
            return false;
        }

        // Überprüfung ob gegebenes Jahr Julianisch oder Gregorianisch ist
        boolean greg = isGregorian(day, month, year);
        
        // Überprüfen ob gegebenes Jahr ein Schaltejahr ist
        boolean leap = isLeapYear(year, greg);

        // Müsste auch passen
        if (leap && (month == 2) && (day > 29)) {
            return false;
        }

        // Hier ist glaub ich der Fehler drin...?
        if ((month == 1) || (month == 3) || (month == 5) || (month == 7)
                || (month == 8) || (month == 10) || (month == 12) && day > 31) {
            return false;
        }

        // Oder auch hier...?
        if ((month == 4) || (month == 6) || (month == 9) || (month == 11)
                && day > 30) {
            return false;
        }

        return true;
    }

Also die erste if-Abfrage kümmmert sich um den Zeitraum vom 5.10.1582 bis 14.10.1582, da diese ja gestrichen wurden um die Schalttage bei der Umstellung vom julianischen auf den gregorianischen Kalender abzubauen.

Die Methode isGregorian stellt fest ob ich mich im jul. oder greg. Kalender befinde.
Der gregorianische soll bei mir ab 1.10.1582 gelten.

Die Methode isLeapYear soll zeigen ob ich ein Schaltjahr habe oder nicht. Schaltjahre sollen im jul. Kalender jedes 4te sein (Jahr 1 nicht) und im greg. Kalender soll jedes durch 4 teilbare aber nicht durch 100 teilbare soll ein Schaltjahr sein oder jedes durch 400 teilbare soll ein Schaltjahr sein.

Bei meinen Testläufen habe ich aber immer wieder ein oder mehrere Datum dabei bei denen meine Methode isValidDate falsch läuft. Ich habe die Fehlerquelle schon etwas eingekreist und glaube der Hund liegt in den letzten beiden if-Abfragen begraben. Ich peils einfach nicht mehr. Evtl seh ich den Wald vor lauter Bäumen nicht mehr...

Gibts eigentlich in Java eine "elegantere" Vorgehensweise um solche if-Abfragen zu "umgehen"?

Bin für jede Unterstützung dankbar!
 
S

SlaterB

Gast
gib doch mal ein festes Beispiel, für welche genauen Eingaben kommt welche genaue falsche Ausgabe?

läuft month von 1-12 oder 0-11?

die vorletzte Bedingung ließe sich auch vereinfachen:

if (day > 31) {
return false;
}

könnte dann theoretisch auch ganz an den Anfang,
genausogut kannst du prüfen ob month > 12


du musst noch prüfen, ob in einem Nicht-Schaltjahr nicht der 29. Februar eingegeben wird
 

Souljacker

Mitglied
Also hier meine Testlaufprotokoll:
calendar> v 4 10 1582
Date 4 10 1582 is valid!

calendar> v 5 10 1582
Date 5 10 1582 is NOT valid!

calendar> v 14 10 1582
Date 14 10 1582 is NOT valid!

calendar> v 15 10 1582
Date 15 10 1582 is valid!

calendar> v 1 -1 2000
Date 1 -1 2000 is NOT valid!

calendar> v 0 1 2000
Date 0 1 2000 is NOT valid!
calendar> v 32 1 2000

Date 32 1 2000 is valid!
calendar> v 1 -1 2000

Date 1 -1 2000 is NOT valid!
calendar> v 1 0 2000
Date 1 0 2000 is NOT valid!
calendar> v 1 13 2000
Date 1 13 2000 is NOT valid!

calendar> v 29 2 2000
Date 29 2 2000 is valid!

calendar> v 30 2 2000
Date 30 2 2000 is NOT valid!
calendar> v 28 2 2000
Date 28 2 2000 is valid!

calendar> v 29 2 1500
Date 29 2 1500 is valid!

calendar> v 30 2 1500
Date 30 2 1500 is NOT valid!

calendar> v 1 1 1600
Date 1 1 1600 is valid!

calendar> v 29 1 2000
Date 29 1 2000 is valid!
calendar> v 31 1 2000
Date 31 1 2000 is valid!

calendar> v 32 1 2000
Date 32 1 2000 is valid!

calendar> v 29 4 2000
Date 29 4 2000 is valid!
calendar> v 30 4 2000
Date 30 4 2000 is valid!

calendar> v 31 4 2000
Date 31 4 2000 is valid!

calendar>

Also ich habe die beiden letzten if-Abfragen auskommentiert und das obige Protokoll angefertigt. Die ROTEN sind falsch (weil ich eben die letzten beiden if-Abfragen auskommentiert habe). wenn ich sie aber drin lasse stimmen bei den anderen einige wieder nicht.

Hier noch meine isLeapYear-Methode:
Code:
boolean isLeapYear(int year, boolean gregorian) {

        boolean leapYear = false;

        if (gregorian) {
            if ((year % 400) == 0) {
                leapYear = true;
            }

            if (((year % 100) != 0) && ((year % 4) == 0)) {
                leapYear = true;
            }
        } else {
            if ((year % 4) == 0) {
                leapYear = true;
            }
        }
        return leapYear;
    }

Und meine isGregorian-Methode:
Code:
boolean isGregorian(int day, int month, int year) {

        if ((year <= 1582) && (month < 10)) {

            return false;
        }

        return true;
    }
 
S

SlaterB

Gast
ich hab ja schon einiges geschrieben, welches einige deiner roten Fälle beheben wird,
da bringt diese Liste also eher wenig
 

Souljacker

Mitglied
YEEEEHA! Jetzt klappts fast...

Jetzt hab ich nur noch das Problem das wenn ich auf Monate teste, die 30 Tage haben (04, 06, 09 und 11) es nicht funktioniert...

TESTPROTOKOLL:

calendar> v 29 4 2000
Date 29 4 2000 is NOT valid!

calendar> v 30 4 2000
Date 30 4 2000 is NOT valid!

calendar> v 31 4 2000
Date 31 4 2000 is NOT valid!



Uff ich seh echt den Wald vor lauter Bäumen nicht mehr...um so länger ich drauf schaue, um so weniger wills mir einleuchten... :bahnhof: Aber das ist jetzt vermutlich das Problem das du vorhin angesprochen hast:
du musst noch prüfen, ob in einem Nicht-Schaltjahr nicht der 29. Februar eingegeben wird

Oder lieg ich da falsch?
 

Murray

Top Contributor
Wenn Dein Code immer noch so aussieht
Code:
        // Hier ist glaub ich der Fehler drin...?
        if ((month == 1) || (month == 3) || (month == 5) || (month == 7)
                || (month == 8) || (month == 10) || (month == 12) && day > 31) {
            return false;
        }

        // Oder auch hier...?
        if ((month == 4) || (month == 6) || (month == 9) || (month == 11)
                && day > 30) {
            return false;
        }

dann steckt der Fehler in der Nichtberücksichtigung des Boole'schen Äquivalents zur Regel "Punktrechnung geht vor Strichrechnung": die UND-Verknüpfung hat Vorrang vor der ODER-Verknüpfung, oder mit Klammern ausgedrückt:
Code:
(a || b && c) == (a || (b && c))
Du musst also Klammern setzen.
 
S

SlaterB

Gast
ich denke nicht, dass ein fehlender Test eine unverständliche Ablehnung eines Datums zur Folge hat,
um zu erkennen, warum 29 4 2000 nicht akzeptiert wird, ist die Kenntnis des Quellcodes dienlich

edit: oder siehe Murray
 

Landei

Top Contributor
Code:
boolean isGregorian(int day, int month, int year) {
  return year > 1582 || (year == 1582 && month >= 10);
}

sonst wären alle Oktober, November und Dezember vor 1582 auch gregorianisch :)
 

Souljacker

Mitglied
Jupp jetzt passts.... :D

Code sieht jetzt so aus:
Code:
boolean isValidDate(int day, int month, int year) {

        if ((year == 1582) && (month == 10)) {
            if ((day == 5) || (day == 6) || (day == 7) || (day == 8)
                    || (day == 9) || (day == 10) || (day == 11) || (day == 12)
                    || (day == 13) || (day == 14)) {
                return false;
            }
        }

        if ((day < 1) || (month > 12) || (month < 1) || (year < 1)) {
            return false;
        }

        
        boolean greg = isGregorian(day, month, year);
        boolean leap = isLeapYear(year, greg);

        if (leap && (month == 2) && (day > 29)) {
            return false;
        }

        if (day > 31){
            return false;
        }
        if (((month == 4) || (month == 6) || (month == 9) || (month == 11))
                && (day > 30)) {
            return false;
        }

        return true;
    }

äh, wie meinst du das
um zu erkennen, warum 29 4 2000 nicht akzeptiert wird, ist die Kenntnis des Quellcodes dienlich

Soll ich hier den ganzen Quelltext posten? Wenn ja, dann aber ohne Gewähr weil der noch ziemlich unvollständig ist bzw. nur so von Bugs wimmelt...

@Murray: Danke für den Tipp! Boolsche Regeln hab ich zwar auch mal gelernt...aber ich wär jetzt nie drauf gekommen!

@Landei: Danke! Wieder ein Fehler weniger...
 
S

SlaterB

Gast
> Soll ich hier den ganzen Quelltext posten?

nur den der Methode, hast du ja nun aktualisiert getan und war auch nicht mehr nötig,

aber so kann ich noch mal reinschauen, und sehe:

day > 31 könntest du noch in
if ((day < 1) || (month > 12) || (month < 1) || (year < 1)) {
miteinbauen


in einem Nicht-Schaltjahr ist der 29. Februar immer noch erlaubt
 

Souljacker

Mitglied
Meintest du in etwa so:
Code:
boolean isValidDate(int day, int month, int year) {

        if ((year == 1582) && (month == 10)) {
            if ((day == 5) || (day == 6) || (day == 7) || (day == 8)
                    || (day == 9) || (day == 10) || (day == 11) || (day == 12)
                    || (day == 13) || (day == 14)) {
                return false;
            }
        }

        if ((day < 1) || (month > 12) || (month < 1) || (year < 1) || (day > 31) ) {
            return false;
        }

        
        boolean greg = isGregorian(day, month, year);
        boolean leap = isLeapYear(year, greg);

        if (leap && (month == 2) && (day > 29)) {
            return false;
        }

        if (!leap && (month == 2) && (day > 28)){
            return false;
        }
        
        if (((month == 4) || (month == 6) || (month == 9) || (month == 11))
                && (day > 30)) {
            return false;
        }

        return true;
    }

Jetzt hab ich noch eine andere Frage:
Es ist doch auch möglich ein Java-Programm in der Form: "java Programmname.java < Dateiname" zu starten. Aus der Datei soll er dann die Aufrufe auslesen. Wie muss den die Datei dann aussehen? Einfache Textdatei (welche Zeichenkodierung?)? Innerhalb der Datei die Aufrufe wie trennen (durch Strichpunkt?)?

Ich stell mir das so vor:
Code:
v 12 1 2000; v 10 10 1582; usw.
Dann bräuchte ich meine Testfälle nicht immer neu in die Konsole hämmern...und weiß jemand evtl wie ich dann ECLIPSE zu dem oben erwähnten Startvorgang bewegen kann?
 
S

SlaterB

Gast
in der Textdatei so eingeben wie in der Konsole,
also z.B. Zeilenumbrüche wenn du vorher ständig Enter gedrückt hast

zu Eclise-Datei kann ich nicht sagen

-----

ich schreibe meine Testwerte in einem solchen Fall in den Quelltext,
entweder als String-Liste oder gleich als mehrere Ints oder als Objekte der neuen Klasse Eingabedaten,
oder gleich Date/ Calendar

oder du schreibst sie in eine Datei und fügst in den Quellcode nur den Dateinamen ein,
dann mit Datei-Lade-Methoden die Datei laden
das wäre auch unabhängig von Start-Parametern
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
D Map<String, Integer> sortieren und der reinfolge nach die Glieder abfragen Java Basics - Anfänger-Themen 3
onlyxlia Anzahl Random Zahlen mit Scanner abfragen und in Array speichern Java Basics - Anfänger-Themen 10
ven000m Bitcoin Blockhöhe abfragen Java Basics - Anfänger-Themen 12
S If abfragen (+, - , /, *) Java Basics - Anfänger-Themen 13
M Dialogbox solange abfragen, bis gültige Wert-Eingabe Java Basics - Anfänger-Themen 12
Phash Websocket abfragen Java Basics - Anfänger-Themen 1
volcanos List & ArrayList nach Familiennamen abfragen Java Basics - Anfänger-Themen 57
E schneller von der Datenbank abfragen Java Basics - Anfänger-Themen 15
M Checkbox abfragen und Radiobutton Group zurücksetzen Java Basics - Anfänger-Themen 1
L Datenpaare abfragen Java Basics - Anfänger-Themen 11
O ADT Graph nach größe Abfragen Java Basics - Anfänger-Themen 42
B Serial port abfragen Java Basics - Anfänger-Themen 18
F Ordner auf alle Unterdatein abfragen Java Basics - Anfänger-Themen 3
N Abfragen eines Textes aus einem JTextField in Java, Funktion, CardLayout, Java Basics - Anfänger-Themen 2
S boolean Wert von mehreren int Möglichkeiten abfragen ? Java Basics - Anfänger-Themen 4
H Variablen Methode zum Abfragen von Variablen aus Subklassen Java Basics - Anfänger-Themen 9
T Erste Schritte Textfeld abfragen ob etwas enthalten ist. Java Basics - Anfänger-Themen 17
S Asynchrone Socket-Abfragen Java Basics - Anfänger-Themen 5
S mehrfache if-Abfragen - beste Lösung Java Basics - Anfänger-Themen 1
E Abfragen des SimpleDateFormats Java Basics - Anfänger-Themen 1
L int array abfragen Java Basics - Anfänger-Themen 16
T Variablen Var aus While-Schleife abfragen -.-' Java Basics - Anfänger-Themen 9
Y Mehrdimensionales Array diagonal abfragen. Java Basics - Anfänger-Themen 5
S Datenbank auf Knopfdruck abfragen Java Basics - Anfänger-Themen 8
T if abfragen verkürzen Java Basics - Anfänger-Themen 5
M Wo Hilfsvariablen abfragen? Java Basics - Anfänger-Themen 1
M Farben/Color Abfragen von Farben innerhalb einer Methode Java Basics - Anfänger-Themen 9
M "Exceptions abfragen" Java Basics - Anfänger-Themen 6
M Frage nach BestPractice in if-Abfragen Java Basics - Anfänger-Themen 1
P Anlegen und Abfragen von Array List Java Basics - Anfänger-Themen 4
R IF Abfragen Java Basics - Anfänger-Themen 8
R If Abfragen Problem! Java Basics - Anfänger-Themen 4
I Button abfragen ob er geklickt wurde Java Basics - Anfänger-Themen 4
C If Abfragen Problem Java Basics - Anfänger-Themen 46
I Drei booleans abfragen Java Basics - Anfänger-Themen 2
R Input/Output Java String abfragen Java Basics - Anfänger-Themen 3
A Vokabel abfragen Java Basics - Anfänger-Themen 3
R Datentypen Datentyp eines Werts in einer Textdateizeile abfragen und ändern Java Basics - Anfänger-Themen 4
N Best Practice Stilistische Anwendung von if/else-Abfragen Java Basics - Anfänger-Themen 7
E Checkboxen abfragen Java Basics - Anfänger-Themen 10
H if abfragen Java Basics - Anfänger-Themen 38
C TreeMap Abfragen Problem Java Basics - Anfänger-Themen 7
S Abfragen wenn das ende einer Tabelle erreicht ist Java Basics - Anfänger-Themen 8
B mehrere Abfragen zusammenfügen Java Basics - Anfänger-Themen 3
H durch Schleife 50 Variablen abfragen Java Basics - Anfänger-Themen 8
B If abfragen! Java Basics - Anfänger-Themen 9
J checkbox status abfragen und drucken Java Basics - Anfänger-Themen 13
M AWT Applet - Button aus anderer Klasse abfragen Java Basics - Anfänger-Themen 4
F Bedingungen mit Abfragen verknüpfen Java Basics - Anfänger-Themen 7
P länge von array abfragen? Java Basics - Anfänger-Themen 2
Gossi Input/Output Datei Lesen, inhalt abfragen, speichern Java Basics - Anfänger-Themen 5
T jNumberField auf null abfragen Java Basics - Anfänger-Themen 5
Z Erste Schritte LinkedList Werte abfragen und vergleichen Java Basics - Anfänger-Themen 3
S Input/Output Welche Möglichkeiten Eingabe von User abfragen Java Basics - Anfänger-Themen 5
H Checkboxstatus abfragen Java Basics - Anfänger-Themen 10
S unzulässigen Wert abfragen - aber wo Java Basics - Anfänger-Themen 3
eLogic Aktive Internetverbindung abfragen Java Basics - Anfänger-Themen 21
B Abfragen eines Preises.. Java Basics - Anfänger-Themen 20
D Touchpad abfragen?! Java Basics - Anfänger-Themen 9
D Abfragen ob Excel-Dateien Makros enthalten? Java Basics - Anfänger-Themen 4
B Abfragen eines Excel-Feldes auf null Java Basics - Anfänger-Themen 17
B GridLayout - elemente mit Maus abfragen Java Basics - Anfänger-Themen 3
B Daten in Instanz einer Klasse ändern / abfragen Java Basics - Anfänger-Themen 12
M Datentypen String mit Trennzeichen abfragen Java Basics - Anfänger-Themen 7
D GUI Checkboxen in allen Klassen abfragen? Java Basics - Anfänger-Themen 5
B OOP String auf bestimmte Zeichen abfragen Java Basics - Anfänger-Themen 4
M Double.NaN abfragen Java Basics - Anfänger-Themen 6
J Performance Vergleich von if-Abfragen mit mehreren Bedingungen Java Basics - Anfänger-Themen 9
H Objecttyp abfragen... Java Basics - Anfänger-Themen 11
N Zeilenanzahl einer TXT abfragen..? Java Basics - Anfänger-Themen 11
S Bremsen 3 IF-Abfragen ein Programm? Java Basics - Anfänger-Themen 7
T scanner bestimmtes format abfragen Java Basics - Anfänger-Themen 5
T JOptionPane mit .showInputDialog: Ergebnis abfragen? Java Basics - Anfänger-Themen 2
S Absatz aus Textdokument abfragen Java Basics - Anfänger-Themen 6
B gedrückte Tasten abfragen Java Basics - Anfänger-Themen 11
L "unschöne" if-Abfragen Java Basics - Anfänger-Themen 4
JFeel-x JComponent<-----Eigenschaften<-- Als Liste abfragen? Java Basics - Anfänger-Themen 8
P Pixelfarbe abfragen Java Basics - Anfänger-Themen 8
J einfache Tastendrücke in einem JFrame abfragen Java Basics - Anfänger-Themen 2
B Aus JTable ImageIcon abfragen Java Basics - Anfänger-Themen 8
hdi Desktop-Auflösung abfragen -> setLocation() von Frame Java Basics - Anfänger-Themen 5
D jeditorpane checkbox abfragen? Java Basics - Anfänger-Themen 7
A Googel Lokal abfragen Java Basics - Anfänger-Themen 7
G in einem inputstream auf " " abfragen? Java Basics - Anfänger-Themen 3
T Rechner-Name abfragen Java Basics - Anfänger-Themen 6
N Event auf JTabbedPane abfragen ? Java Basics - Anfänger-Themen 8
M Maus position abfragen und setzen? Java Basics - Anfänger-Themen 1
L JTabel abfragen ob es eine erste Zeile gibt? Java Basics - Anfänger-Themen 2
G If Abfragen Java Basics - Anfänger-Themen 3
T Variablen Classübergreifen abfragen Java Basics - Anfänger-Themen 6
S Abfragen ob Label enabled ist . Java Basics - Anfänger-Themen 2
M Status von ext. Programm abfragen Java Basics - Anfänger-Themen 2
G [Applet] Mauskkoodinaten abfragen Java Basics - Anfänger-Themen 3
C String.split("") einzelne Positionen abfragen Java Basics - Anfänger-Themen 10
R Vector mit contains abfragen Java Basics - Anfänger-Themen 32
T String splitten und auf fehler abfragen Java Basics - Anfänger-Themen 3
V thread, variable abfragen Java Basics - Anfänger-Themen 14
F Abfragen aber wie ? Java Basics - Anfänger-Themen 7
G JDialog-Status im Frame abfragen Java Basics - Anfänger-Themen 2
V .jar macht keine Datenbank abfragen Java Basics - Anfänger-Themen 3

Ähnliche Java Themen

Neue Themen


Oben