![]() |
Delphi-Version: 10.3 Rio
Erstellen eines Datum-überprüfers
Hallo,
Ich habe das Fach Programmstrukturen 1 an der Fachhochschule, nun müssen wir ein Programm schreiben das ein Datum überprüft, natürlich auch ob Schaltjahr ist oder nicht. Jetzt wird bei mir alles korrekt überprüft außer das Schaltjahr, da bleibt der Compiler immer stehen wenn es kein Schaltjahr ist. Ich habe alles probiert und nichts möchte klappen. Wäre dankbar über jede Hilfe. program ueb03; {$APPTYPE CONSOLE} {$R+,Q+ X-} uses System.SysUtils; var Tag: integer; Monat: integer; Jahr: integer; begin write('Bitte den Tag eingeben '); readln(Tag); write('Bitte den Monat eingeben '); readln(Monat); write('Bitte das Jahr eingeben '); readln(Jahr); if (Tag >= 1) and (Tag <= 31) then if (Monat >= 1) and (Monat <= 12) then if (Jahr >= 1) and (Jahr <= 3000)then begin if(Jahr mod 4 = 0) and(Jahr mod 100 <> 0) or(Jahr mod 400 = 0)then if (Tag = 29) then case Monat of 2: writeln(Tag,' ist zulässig'); end; begin if (Tag <= 31) then case Monat of 1,3,5,7,8,10,12: writeln('Der ',Tag,'. ist gültig.') end; begin if (Tag <= 30) then case Monat of 4,6,9,11: writeln('Der ',Tag,'. ist gültig') end else writeln(Tag,'.',Monat,'.', Jahr, ' ist unzulässig.'); readln; end; end; end else begin writeln('Jahr ungültig.'); readln; end else begin writeln('Monat ungültig.'); readln; end else begin writeln('Tag ungültig.'); readln; end; end. |
AW: Erstellen eines Datum-überprüfers
Es wäre cool, wenn Du den Code als "Delphi-Code einfügen" (Helm-Symbol) und einrücken würdest.
Das würde die Lesbarkeit schon mal deutlich verbessern. Bist Du sicher, dass Deine Abfragen korrekt funktionieren? Wenn ich z.B. den 31.1.2021 eingebe, wird folgendes ausgegeben: Zitat:
Statt der IF-Verschachtelung könntest Du z.B. auch mit einer Repeat-Schleife arbeiten. Als Beispiel für die Eingabe und Überprüfung des Tags, zB:
Delphi-Quellcode:
Was meinst Du mit "der Compiler bleibt stehen"?
// Überprüfung ob der Tag zwischen 1...31 liegt
var iTag : Integer; sEingabe : String; begin Repeat write('Bitte den Tag eingeben: '); readln(Eingabe); Tag := StrToIntDef(Eingabe, 1); if (Tag < 1) or (Tag > 31) then WriteLn('Die Eingabe ist ungültig!'); until (Tag > 0) and (Tag <=31); ... |
AW: Erstellen eines Datum-überprüfers
Delphi-Code bitte in [DELPHI]...[/DELPHI] einschließen.
Aber selbst mit deiner eigenwilligen Einrückung, ist es schwer zu lesen. Tipp: ![]() ![]() Compiler bleibt steht? > Mit welcher Fehlermeldung? Ich denke mal du meinst dein "Programm" und nicht den Compiler, was manchmal nichts anzeigt (weil deine Prüfungen falsch sind). Lösung: Verwende den Debugger und schau nach, was dein Programm wirklich macht. ![]() ![]() ![]() ![]() Tipp: statt erst
Delphi-Quellcode:
und dann jeweils ein CASE, nimm besser erst nur ein CASE und darin dann die IF
if Tag
Beim ersten Case hast das ELSE vergessen. Und falls ihr noch irgendwann zum Optiomieren/Verkürzen kommt, dann ![]() ![]() ![]() |
AW: Erstellen eines Datum-überprüfers
Ist etwas OffTopic. Aber es ist traurig zu sehen, wie kaputt die Rechtschreibung und Einrückung des Codes im ersten Post ist wenn man bedenkt
Zitat:
|
AW: Erstellen eines Datum-überprüfers
Mal aus Spass ein Pascalscript (ohne Verwendung irgendwelcher Datumsfunktionen):
Delphi-Quellcode:
@DieDolly:
program Kalender;
function IfThen(b : Boolean; sOk : String; sNotOk : String) : String; begin case b of true : Result := sOk; false : Result := sNotOk; end; end; function IsSchaltjahr(Jahr : Integer) : Boolean; begin Result := (Jahr mod 4 = 0) and ((Jahr mod 100 <> 0) or (Jahr mod 400 = 0)); end; function IsBetween(i : Integer; iMin : Integer; iMax : Integer): Boolean; begin Result := (i >= iMin) and (i <= iMax); end; function IsTagOk(Tag : Integer; Monat : Integer; Jahr : Integer) : Boolean; begin Result := false; if IsBetween(Monat,1,12) then begin case Monat of 1,3,5,7,8,10,12 : Result := IsBetween(Tag,1,31); 2 : case IsSchaltjahr(Jahr) of true : Result := IsBetween(Tag,1,29); false : Result := IsBetween(Tag,1,28); end; 4,6,9,10 : Result := IsBetween(Tag,1,30); end; end; end; var Jahr : Integer; Monat : Integer; Tag : Integer; begin Write('Bitte das Jahr eingeben:'); ReadLn(Jahr); Write('Bitte den Monat eingeben:'); ReadLn(Monat); Write('Bitte den Tag eingeben:'); ReadLn(Tag); // Kalenderreform von 1582, davor gilt die Schaltjahrberechnung nicht. if IsBetween(Jahr,1583,3000) then begin WriteLn(Format('Das Jahr %d ist gültig und %s Schaltjahr.',[Jahr, IfThen(IsSchaltjahr(Jahr),'ein','kein')])); WriteLn(Format('Der Monat %d ist %sgültig.',[Monat, IfThen(IsBetween(Monat,1,12),'','un')])); WriteLn(Format('Der Tag %d ist %sgültig.',[Tag, IfThen(IsTagOk(Tag, Monat, Jahr),'','un')])); end else begin WriteLn(Format('Das Jahr %d liegt außerhalb des Gültigkeitsbereiches.',[Jahr])); end; end. Habe schon deutlich "schlimmeren" Code von promovierten Informatikern gesehen. Wir haben seinerzeit jedenfalls nicht gelernt, wie man Code "schön" schreibt, sondern nur, wie man die für die Problemstellung erforderliche Logik richtig entwickelt und dann "irgendwie" funktionsfähig implementiert. Und ja: Viele Implementierungsfehler lassen sich in "schöner Quelltextoptik" deutlich leichter auffinden, vor allem, wenn die optische Struktur der logischen Struktur entspricht. ;-) |
AW: Erstellen eines Datum-überprüfers
Verwende System.SysUtils.EncodeDate( ) und reagiere auf Exceptions. Da lernst du fast mehr ;-)...
|
AW: Erstellen eines Datum-überprüfers
Frage: Geht es darum Delphi zu lernen oder darum die Grundlagen der Kalenderberechnung zu lernen?
|
AW: Erstellen eines Datum-überprüfers
Vielen Dank für eure Mühe,
Sorry für die schlechte Lesbarkeit, ich bin noch ein blutiger Anfänger der vor zwei Wochen bei null angefangen hat. Schleifen sowie function haben wir noch nicht gehabt und dürfen wir somit auch noch nicht verwenden. Ich werde es mal mit dem Debugger durchgehen vielleicht finde ich das Problem. |
AW: Erstellen eines Datum-überprüfers
Zitat:
Wäre ich dort, würde ich alles verwenden, was ich kenne, und nicht das, was ich darf. |
AW: Erstellen eines Datum-überprüfers
Delphi-Quellcode:
Habe mir erlaubt den Quelltext zu formatieren und im Delphi Tag einzubetten. (Aber nichts getestet oder daran verändert.)
program ueb03;
{$APPTYPE CONSOLE} {$R+,Q+ X-} uses System.SysUtils; var Tag: integer; Monat: integer; Jahr: integer; begin write('Bitte den Tag eingeben '); readln(Tag); write('Bitte den Monat eingeben '); readln(Monat); write('Bitte das Jahr eingeben '); readln(Jahr); if (Tag >= 1) and (Tag <= 31) then if (Monat >= 1) and (Monat <= 12) then if (Jahr >= 1) and (Jahr <= 3000) then begin if (Jahr mod 4 = 0) and (Jahr mod 100 <> 0) or (Jahr mod 400 = 0) then if (Tag = 29) then case Monat of 2: writeln(Tag, ' ist zulässig'); end; begin if (Tag <= 31) then case Monat of 1, 3, 5, 7, 8, 10, 12: writeln('Der ', Tag, '. ist gültig.') end; begin if (Tag <= 30) then case Monat of 4, 6, 9, 11: writeln('Der ', Tag, '. ist gültig') end else writeln(Tag, '.', Monat, '.', Jahr, ' ist unzulässig.'); readln; end; end; end else begin writeln('Jahr ungültig.'); readln; end else begin writeln('Monat ungültig.'); readln; end else begin writeln('Tag ungültig.'); readln; end; end. @DieDolly! Helfe ihm doch einfach als über ihn herzuziehen er kann nichts für die Vorschriften die man ihm auferlegt. Just my 2 Cent! |
AW: Erstellen eines Datum-überprüfers
Es ist jedem Schüler oder Studenten selber überlassen, seinen Code so anzulegen, dass er verständlich ist.
Da interessiert es wenig, was eine Lehrperson dazu sagt. |
AW: Erstellen eines Datum-überprüfers
Einige Ausgaben sind mit einem ReadLn am Ende, aber andere nicht.
Wobei, wenn alle Ausgaben es hätten, dann würde es auch reichen das hinter allem Code zu machen, also nur einmal ganz am Ende. Vor allem ist eine halbwegs orgendliche Formatierung/Einrückung auch dafür gut, dass man den Programmablauf besser erkennen kann. Das, was man mit dem Debugger physisch machen kann, kann man so auch mit dem Finger durchgehn, also wo wann das Programm durchläuft, wenn man sich eine gewisse Anfangsbedingung (Tag/Monat/Jahr) überlegt hat. Ja, der Style-Guide ist mehr ein Vorschlag und keine Pflicht, aber um erstmal überhaupt ein bischen Struktur in seinen Code zu bekommen, darf man da gern sich das Eine oder Andere abgucken. |
AW: Erstellen eines Datum-überprüfers
Ich habe jetzt das nochmal überarbeitet und zusammengefasst, jetzt besteht aber das Problem das das Programm nach der Abfrage des Datums endet.
Der Debugger hat mir hierzu auch nichts mitgeteilt.
Delphi-Quellcode:
{$APPTYPE CONSOLE}
{$R+,Q+ X-} uses System.SysUtils; var Tag: integer; Monat: integer; Jahr: integer; begin write('Bitte den Tag eingeben '); readln(Tag); write('Bitte den Monat eingeben '); readln(Monat); write('Bitte das Jahr eingeben '); readln(Jahr); if (Tag >= 1) and (Tag <= 31) then if (Monat >= 1) and (Monat <= 12) then if (Jahr >= 1) and (Jahr <= 3000)then begin case Monat of 2: if(Jahr mod 4 = 0) and (Jahr mod 100 <> 0) or (Jahr mod 400 = 0) and (Tag = 29) then writeln(Tag,' ist zulässig'); 1,3,5,7,8,10,12: if (Tag <= 31) then writeln('Der ',Tag,'. ist gültig.'); 4,6,9,11: if (Tag <= 30) then writeln('Der ',Tag,'. ist gültig.'); else writeln('ungültig') end; end else begin writeln('Jahr ungültig.'); readln; end else begin writeln('Monat ungültig.'); readln; end else begin writeln('Tag ungültig.'); readln; end; end. |
AW: Erstellen eines Datum-überprüfers
vielleciht hilft dies : ungetestet
Delphi-Quellcode:
var
Tag: integer; Monat: integer; Jahr: integer; anzahl_tage:Byte; begin write('Bitte den Tag eingeben '); readln(Tag); write('Bitte den Monat eingeben '); readln(Monat); write('Bitte das Jahr eingeben '); readln(Jahr); if ((tag>=1) and (tag<=31)) and ((monat>=1) and (monat<=12)) and (jahr>1582) then begin if (Jahr mod 4 = 0) and (Jahr mod 100 <> 0) or (Jahr mod 400 = 0) then anzahl_tage:=29 else anzahl_tage:=28; case monat of 1,3,5,7,8,10,12:if (tag>=1) and (tag<=31) then writeln('Datum Ok.') else writeln('Datum nicht Ok.'); 2:if (tag>=1) and (tag<=anzahl_tage) then writeln('Datum Ok.') else writeln('Datum nicht Ok.') else if (tag>=1) and (tag<=30) then writeln('Datum Ok.') else writeln('Datum nicht Ok.'); end; end else writeln('Eingabe ungültig'); readln; end. |
AW: Erstellen eines Datum-überprüfers
Zitat:
Respektiert man den, würde man Fehler, so denke ich, sofort finden. Drückt im Editor mal STRG+D und benutzt begin und end etwas öfter! |
AW: Erstellen eines Datum-überprüfers
Nochmal einen Abschnitt überarbeitet:
Delphi-Quellcode:
@DieDolly
if (Jahr >= 1) and (Jahr <= 3000) then begin
case Monat of 2: begin if (Jahr mod 4 = 0) and (Jahr mod 100 <> 0) or (Jahr mod 400 = 0) and (Tag = 29) then begin writeln(Tag,' ist zulässig'); end; // Hier fehlt wohl eine Else. // Was soll denn bitteschön in einem Nichtschaltjahr geschehen? // Und was ist mit den übrigen Tagen das Februar? end; 1,3,5,7,8,10,12: begin if (Tag <= 31) then begin writeln('Der ',Tag,'. ist gültig.'); end; // Else mit Hinweis auf ungültigen Tag? end; 4,6,9,11: begin if (Tag <= 30) then begin writeln('Der ',Tag,'. ist gültig.'); end; // Else mit Hinweis auf ungültigen Tag? end; else writeln('ungültig') end; end; Der Delphi-Style-Guide ist eine herstellerinterne Richtlinie und nicht allgemeinverbindlich. Man kann sich dran halten, muss man aber nicht. Abgesehen davon: Wenn man sich dran hällt, heißt das noch lange nicht, dass es hier im Forum dann auch so angezeigt wird. Der Parser für die Syntaxhervorhebung innerhalb der Delphi-Tags hat da durchaus seine eigenen Ansichten. (Sieht man hier z. B. sehr gut bei den Case-Anweisungen. Im Editor sehen die vollkommen anders aus. [edit] Abgesehen davon, dass wohl auch Browser und dort gewählte Schriftart und -größe die Optik und Style-Guide-Konformität massiv zu beeinflussen scheinen (sowohl positiv als auch negativ, ja nach dem, was da so genutzt wird.) [/edit]) PS: Poste doch bitte eine korrekte Lösung, die allen Deinen Anforderungen entspricht. Dann können wir das gerne als ultimativ richtig interpretieren ;-) |
AW: Erstellen eines Datum-überprüfers
@Delphi.Narium Vielen Vielen Dank für deine Hilfe, ich müsste es jetzt hinbekommen haben. Wenn ihr noch einen Fehler entdeckt könnt Ihr mich gerne darauf hinweisen.
Jetzt fehlt mir nur noch das Integrieren einer Berechnung ob an diesem Tag Ostern ist, dann kann ich es abgeben.:-D
Delphi-Quellcode:
{$APPTYPE CONSOLE}
{$R+,Q+ X-} uses System.SysUtils; var Tag: integer; Monat: integer; Jahr: integer; begin write('Bitte den Tag eingeben '); readln(Tag); write('Bitte den Monat eingeben '); readln(Monat); write('Bitte das Jahr eingeben '); readln(Jahr); if (Tag >= 1) and (Tag <= 31) then if (Monat >= 1) and (Monat <= 12) then if (Jahr >= 1) and (Jahr <= 3000) then case Monat of 2: begin if (Jahr mod 4 = 0) and (Jahr mod 100 <> 0) or (Jahr mod 400 = 0) then begin if (Tag <= 29) then begin writeln(Tag, ' ist zulässig.'); readln; end else begin writeln(Tag, ' ist unzulässig.'); readln; end; end else begin if not(Jahr mod 4 = 0) and not(Jahr mod 100 <> 0) or not(Jahr mod 400 = 0) then begin if (Tag <= 29) then begin writeln(Tag, ' ist unzulässig.'); readln; end; end; end; end; 1, 3, 5, 7, 8, 10, 12: begin if (Tag <= 31) then begin writeln('Der ', Tag, '. ist gültig.'); readln; end else begin writeln('ungültig'); readln; end; end; 4, 6, 9, 11: begin if (Tag <= 30) then begin writeln('Der ', Tag, '. ist gültig.'); readln; end else begin writeln('ungültig'); end; end; end else begin writeln('Jahr ungültig.'); readln; end else begin writeln('Monat ungültig.'); readln; end else begin writeln('Tag ungültig.'); readln; end; end. |
AW: Erstellen eines Datum-überprüfers
Suchmaschine marsch:
![]()
Code:
Die Osterformel: So berechnen Sie das Datum
a = Jahr mod 4 b = Jahr mod 7 c = Jahr mod 19 d = (19c + 24) mod 30 e = (2a + 4b + 6d + 5) mod 7 f = (c + 11d + 22e) / 451 Der Ostersonntag wird daraus wie folgt errechnet: 22 + d + e - 7f Ist dieses Ergebnis größer als 31, so liegt Ostern im April. Dann muss folgende Formel für die Berechnung des Ostersonntag angewandt werden: 22 + d + e - 7f - 31 = d + e - 7f - 9. |
AW: Erstellen eines Datum-überprüfers
Zitat:
Und nun schau dir darin alles nochmals ganz genau an. Wozu "nochmal" das IF für Schaltjahre? Es wurde schon geprüft, also kann es dort nur negativ sein. (gut, denn so ist es egal, dass es kein Else gibt) Aber rate mal, was
Delphi-Quellcode:
macht, wenn der Tag 30 oder 31 ist.
if (Tag <= 29) then
Probiere auch mal den 31 April, also was dein Programm da macht. (oder auch nicht) Und bei den 31-tägigen Monaten. (Januar, März, ...) Grundsätzlich wäre dort das ELSE nicht ganz falsch, aber schau mal in die ersten 3 IFs ... Bist du der Meinung, dass hier jemals der Tag größer als 31 sein kann? (oder einfach das erste IF für den Tag weglassen, da innen eh nochmals der Tag überall geprüft wird) |
AW: Erstellen eines Datum-überprüfers
Ich würde die Prüfung vom Jahr über den Monat zum Tag herunter abarbeiten.
Und dem Nutzer nach Möglichkeit auch gleich verraten, was an seinem Wert falsch ist. Beispiel:
Delphi-Quellcode:
program ueb03;
{$APPTYPE CONSOLE} {$R+,Q+ X-} uses SysUtils; var Tag: integer; Monat: integer; Jahr: integer; MaxTage: integer; begin write('Bitte den Tag eingeben '); readln(Tag); write('Bitte den Monat eingeben '); readln(Monat); write('Bitte das Jahr eingeben '); readln(Jahr); if (Jahr >= 1) and (Jahr <= 3000)then begin writeln ('Jahr OK'); if (Monat >= 1) and (Monat <= 12) then begin writeln ('Monat OK'); case Monat of 1,3,5,7,8,10,12: begin MaxTage := 31; end; 2: begin if ( (Jahr mod 4 = 0) and (Jahr mod 100 <> 0) ) or (Jahr mod 400 = 0) then begin MaxTage := 29; end else begin MaxTage := 28; end; end; else begin MaxTage := 30; end; end; if (Tag >=1) and (Tag <= MaxTage) then begin writeln ('Tag OK'); // an dieser Stelle kann man dann noch solche Dinge wie Osterprüfung etc. einbauen und den User informieren end else begin writeln ('Tag ungültig: Wert muss zwischen 1 und ' + IntToStr(MaxTage) + ' liegen!'); end; end else begin writeln('Monat ungültig: Wert muss zwischen 1 und 12 liegen!'); end; end else begin writeln('Jahr ungültig: Wert muss zwischen 1 und 3000 liegen'); end; writeln ('Bitte ENTER drücken'); readln; end. |
AW: Erstellen eines Datum-überprüfers
Zitat:
|
AW: Erstellen eines Datum-überprüfers
Dankeschön, ich habe es nochmal korrigiert, außer das mit dem ersten If da es ja auch überprüft ob der Tag >= 1 ist, falls eine negative Zahl eingegeben wird, sollte es dann die Fehlermeldung anzeigen.
Hier nochmal die korrigierte Version:
Delphi-Quellcode:
{$APPTYPE CONSOLE}
{$R+,Q+ X-} uses System.SysUtils; var Tag: integer; Monat: integer; Jahr: integer; begin write('Bitte den Tag eingeben '); readln(Tag); write('Bitte den Monat eingeben '); readln(Monat); write('Bitte das Jahr eingeben '); readln(Jahr); if (Tag >= 1) and (Tag <= 31) then if (Monat >= 1) and (Monat <= 12) then if (Jahr >= 1) and (Jahr <= 3000) then case Monat of 2: begin if (Jahr mod 4 = 0) and (Jahr mod 100 <> 0) or (Jahr mod 400 = 0) then begin if (Tag <= 29) then begin writeln(Tag, ' ist zulässig.'); readln; end else begin writeln(Tag, ' ist unzulässig.'); readln; end; end else begin if (Tag <= 28) then writeln(Tag, ' ist zulässig.') else writeln(Tag, ' ist unzulässig.'); end; end; 1, 3, 5, 7, 8, 10, 12: begin if (Tag <= 31) then begin writeln('Der ', Tag, '. ist gültig.'); readln; end else begin writeln('Der ', Tag,'. ist ungültig.'); readln; end; end; 4, 6, 9, 11: begin if (Tag <= 30) then begin writeln('Der ', Tag, '. ist gültig.'); readln; end else begin writeln('ungültig'); readln; end; end; end else begin writeln('Jahr ungültig.'); readln; end else begin writeln('Monat ungültig.'); readln; end else begin writeln('Tag ungültig.'); readln; end; end. |
AW: Erstellen eines Datum-überprüfers
Zitat:
|
AW: Erstellen eines Datum-überprüfers
Ist es untersagt die von Delphi bereitgestellten Units zu verwenden?
Eigentlich sollte man doch lernen nichts zu programmieren was es nicht schon gibt, also wozu das Rad neu erfinden? himitsu hat bereits viele vorgefertigte methoden erwähnt. Ich würde ja nach einem reinen vortest (tag >0 <32) (monat >0 <13)) (jahr >0 <=9999) das ganze in ein TDateTime umwandeln ( ![]() Schön zu sehen wie es sich entwickelt, diese ursprünglichen if's waren echt sehr unübersichtlich, Danke an Emil fürs Taggen, das Case ist eine sehr gute alternative Verbesserung, weiter so und Willkommen in der DP! |
AW: Erstellen eines Datum-überprüfers
Zum Spaß noch ein Ansatz:
Delphi-Quellcode:
@KodeZwerg:
var
Tag : Integer; Monat : Integer; Jahr : Integer; TagOK : Boolean; MonatOk : Boolean; JahrOk : Boolean; IstSchaltjahr : Boolean; begin write('Bitte den Tag eingeben '); readln(Tag); write('Bitte den Monat eingeben '); readln(Monat); write('Bitte das Jahr eingeben '); readln(Jahr); TagOk := (Tag >= 1) and (Tag <= 31); MonatOk := (Monat >= 1) and (Monat <= 12); JahrOk := (Jahr >= 1) and (Jahr <= 3000); IstSchaltJahr := (Jahr mod 4 = 0) and (Jahr mod 100 <> 0) or (Jahr mod 400 = 0); if TagOk and MonatOk and JahrOk then begin case Monat of 2: case IstSchaltjahr of true : TagOk := (Tag <= 29); false : TagOk := (Tag <= 28); end; 1, 3, 5, 7, 8, 10, 12 : TagOk := (Tag <= 31); 4, 6, 9, 11 : TagOk := (Tag <= 30); end; end; writeln('Als Datum wurde der ', Tag,'.', Monat,'.', Jahr,' eingegeben:'); case TagOk of true : writeln('Der Tag ', Tag, ' ist gültig.'); false : writeln('Der Tag ', Tag, ' ist ungültig.'); end; case MonatOk of true : writeln('Der Monat ', Monat, ' ist gültig.'); false : writeln('Der Monat ', Monat, ' ist ungültig.'); end; case JahrOk of true : writeln('Das Jahr ', Jahr, ' liegt im zulässigen Bereich.'); false : writeln('Das Jahr ', Jahr, ' liegt ausserhalb des zulässigen Bereiches.'); end; case JahrOk and IstSchaltjahr of true : writeln('Bei dem Jahr ', Jahr,' handelt es sich um ein Schaltjahr.'); false : writeln('Bei dem Jahr ', Jahr,' handelt es sich nicht um ein Schaltjahr.'); end; readln; end. Es geht erstmal darum die Grundzüge des Programmierens und die Umsetzung einer Aufgabenstellung in entsprechende Logik zu lernen. Das dazu Delphi benutzt wird, ist nachrangig. Daher ist es momentan noch nicht hilfreich in Delphi vorhanden Funktionalitäten zu nutzen, auch wenn dies eigentlich naheliegend erscheint. Die delphieigenen Funktionen kann man dann gerne zur Verifizierung der eigenen Ergebnisse nutzen. Dann lernt man direkt beides ;-) |
AW: Erstellen eines Datum-überprüfers
@Delphi.Narium. Super gemacht alles drin und die Rückgabe so wie sie sein sollte.
Kleine Einschränkung Formatierung könnte besser sein. Aber jedem das seine. Meine wäre so! LOL.. ;)
Delphi-Quellcode:
program ueb03;
{$APPTYPE CONSOLE} {$R+,Q+ X-} uses System.SysUtils; var Tag: Integer; Monat: Integer; Jahr: Integer; TagOK: Boolean; MonatOk: Boolean; JahrOk: Boolean; IstSchaltjahr: Boolean; begin write('Bitte den Tag eingeben '); readln(Tag); write('Bitte den Monat eingeben '); readln(Monat); write('Bitte das Jahr eingeben '); readln(Jahr); TagOK := (Tag >= 1) and (Tag <= 31); MonatOk := (Monat >= 1) and (Monat <= 12); JahrOk := (Jahr >= 1) and (Jahr <= 3000); IstSchaltjahr := (Jahr mod 4 = 0) and (Jahr mod 100 <> 0) or (Jahr mod 400 = 0); if TagOK and MonatOk and JahrOk then begin case Monat of 2: case IstSchaltjahr of true: TagOK := (Tag <= 29); false: TagOK := (Tag <= 28); end; 1, 3, 5, 7, 8, 10, 12: TagOK := (Tag <= 31); 4, 6, 9, 11: TagOK := (Tag <= 30); end; end; writeln('Als Datum wurde der ', Tag, '.', Monat, '.', Jahr, ' eingegeben:'); case TagOK of true: writeln('Der Tag ', Tag, ' ist gültig.'); false: writeln('Der Tag ', Tag, ' ist ungültig.'); end; case MonatOk of true: writeln('Der Monat ', Monat, ' ist gültig.'); false: writeln('Der Monat ', Monat, ' ist ungültig.'); end; case JahrOk of true: writeln('Das Jahr ', Jahr, ' liegt im zulässigen Bereich.'); false: writeln('Das Jahr ', Jahr, ' liegt ausserhalb des zulässigen Bereiches.'); end; case JahrOk and IstSchaltjahr of true: writeln('Bei dem Jahr ', Jahr, ' handelt es sich um ein Schaltjahr.'); false: writeln('Bei dem Jahr ', Jahr, ' handelt es sich nicht um ein Schaltjahr.'); end; readln; end. |
AW: Erstellen eines Datum-überprüfers
Bei diesem ganzen Case true false werfe ich mal IfThen in den Raum.
|
AW: Erstellen eines Datum-überprüfers
Zitat:
tsss.. |
AW: Erstellen eines Datum-überprüfers
hallo,
zur Erinnerung ![]() :-D wurde aber schon drauf hingewiesen #5 Gruß |
AW: Erstellen eines Datum-überprüfers
@KodeZwerg
Leider ist uns die Benutzung von Dingen die wir noch nicht hatten untersagt. Ich verstehe ehrlich gesagt auch nicht warum die uns das Leben nicht leichter machen, aber ich denke die machen das um uns das zu veranschaulichen. |
AW: Erstellen eines Datum-überprüfers
Leute zum Thema der Osternüberprüfung verstehe ich die letzte Gleichung nicht, da beide Seiten der Gleichung ja nicht immer das gleiche ergeben.
Die Osterformel: So berechnen Sie das Datum a = Jahr mod 4 b = Jahr mod 7 c = Jahr mod 19 d = (19c + 24) mod 30 e = (2a + 4b + 6d + 5) mod 7 f = (c + 11d + 22e) / 451 Der Ostersonntag wird daraus wie folgt errechnet: 22 + d + e - 7f Ist dieses Ergebnis größer als 31, so liegt Ostern im April. Dann muss folgende Formel für die Berechnung des Ostersonntag angewandt werden: 22 + d + e - 7f - 31 = d + e - 7f - 9. Ich habe versucht das mal zum Verständnis in ein Quelltext zu übersetzen, da habe ich für beide Seiten der Gleichung jeweils eine Variable deklariert um zu schauen ob immer dasselbe rauskommt.
Delphi-Quellcode:
var
a, b, c, d, e, f: integer; Jahr: integer; Ostersonntag: integer; OsternApril: integer; Ostern2: integer; begin writeln('Jahr eingeben'); readln(Jahr); a := Jahr mod 4; b := Jahr mod 7; c := Jahr mod 19; d := (19 * c + 24) mod 30; e := (2 * a + 4 * b + 6 * d + 5) mod 7; f := (c + 11 * d + 22 * e) div 451; Ostersonntag := 22 + d + e - 7 * f; if (Ostersonntag > 31) then OsternApril := 22 + d + e - 7 * f - 31; Ostern2 := d + e - 7 * f - 9; writeln(OsternApril); writeln(Ostern2); readln; end. |
AW: Erstellen eines Datum-überprüfers
Zitat:
Da es anscheinend auch noch nicht gestattet ist eigene Methoden zu entwerfen, hier als Fließtext Programm:
Delphi-Quellcode:
program Project33;
{$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils; var iJahr, iMonat, iTag, iVollmond, iVollmonde, iSonntag, iMetonischerZyklus, iJahrhundert, iSchaltjahre, iMondPhase: Integer; begin try Write('Jahr zur Berechnung des Ostersonntags eingeben: '); Readln(iJahr); iMetonischerZyklus := (iJahr mod 19) + 1; iJahrhundert := (iJahr div 100) + 1; iSchaltjahre := (3 * iJahrhundert) div 4 - 12; iMondPhase := (8 * iJahrhundert + 5) div 25 - 5; iSonntag := (5 * iJahr) div 4 - iSchaltjahre - 10; // überlaufschutz iVollmonde := (11 * iMetonischerZyklus + 20 + iMondPhase - iSchaltjahre) mod 30; if iVollmonde < 0 then iVollmonde := iVollmonde + 30; if ((iVollmonde = 25) and (iMetonischerZyklus > 11)) or (iVollmonde = 24) then iVollmonde := iVollmonde + 1; iVollmond := 44 - iVollmonde; if iVollmond < 21 then iVollmond := iVollmond + 30; iVollmond := iVollmond + 7 - ((iSonntag + iVollmond) mod 7); if iVollmond > 31 then begin iMonat := 4; iTag := iVollmond - 31; end else begin iMonat := 3; iTag := iVollmond; end; Writeln('Ostersonntag war/ist am ' + IntToStr(iTag) + '.' + IntToStr(iMonat) + '.' + IntToStr(iJahr)); except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; Readln; end. |
AW: Erstellen eines Datum-überprüfers
@KodeZwerg Vielen Dank für deinen Lösungsvorschlag, ich hab es jetzt bereits mit einer anderen Berechnungsmethode gelöst
![]() da die eine Berechnungsmethode wenn Ostern auf März fällt ein falsches Datum ausgegeben hat. Hier mein fertiges Programm mit Osterberechnung, freue mich über jeden Verbesserungsvorschlag:-D.
Delphi-Quellcode:
{$APPTYPE CONSOLE}
{$R+,Q+ X-} uses System.SysUtils; var Tag: integer; Monat: integer; Jahr: integer; Schaltjahr: byte; Gültig: byte; SäkZahl: integer; SäkMondSch: integer; SäkSonnenSch: integer; Mondparameter: integer; KeimVollFrüh: integer; Korrektur: integer; Ostergrenze: integer; ErsterSonnMärz: integer; Osterentfernung: integer; OsternMärz: integer; begin write('Bitte den Tag eingeben '); readln(Tag); write('Bitte den Monat eingeben '); readln(Monat); write('Bitte das Jahr eingeben '); readln(Jahr); if (Tag >= 1) and (Tag <= 31) then if (Monat >= 1) and (Monat <= 12) then if (Jahr >= 1) and (Jahr <= 3000) then begin //Berechnung ob Schaltjahr gültig. if (Jahr mod 4 = 0) and (Jahr mod 100 <> 0) or (Jahr mod 400 = 0) then Schaltjahr := 1 else Schaltjahr := 0; case Monat of // Berechnung ob Datum gültig ist. 1, 3, 5, 7, 8, 10, 12: begin if (Tag < 32) then Gültig := 1 else Gültig := 0 end; 4, 6, 9, 11: begin if (Tag < 31) then Gültig := 1 else Gültig := 0 end; 2: begin if ((Tag < 29 + byte(Schaltjahr > 0))) then Gültig := 1 else Gültig := 0 end; end; if Gültig = 1 then begin //Berechnung ob Datum an Ostern liegt. SäkZahl := Jahr div 100; SäkMondSch := 15 + (3 * SäkZahl + 3) div 4 - (8 * SäkZahl + 13) div 25; SäkSonnenSch := 2 - (3 * SäkZahl + 3) div 4; Mondparameter := Jahr mod 19; KeimVollFrüh := (19 * Mondparameter + SäkMondSch) mod 30; Korrektur := (KeimVollFrüh + Mondparameter div 11) div 29; Ostergrenze := 21 + KeimVollFrüh - Korrektur; ErsterSonnMärz := 7 - (Jahr + Jahr div 4 + SäkSonnenSch) mod 7; Osterentfernung := 7 - (Ostergrenze - ErsterSonnMärz) mod 7; OsternMärz := Ostergrenze + Osterentfernung; //Prüfung um welchen Osterntag es sich handelt. if ((Tag = OsternMärz) and (Monat = 3)) or (((Tag = (OsternMärz - 31)) and (Monat = 4))) then writeln(Tag,'.', Monat,'.', Jahr, ' ist gültig und ist Ostersonntag.') else if ((Tag = (OsternMärz - 2)) and (Monat = 3)) or (((Tag = (OsternMärz - 33)) and (Monat = 4))) then writeln(Tag,'.', Monat, '.', Jahr, ' ist gültig und ist Karfreitag.') else if ((Tag = (OsternMärz + 1)) and (Monat = 3)) or (((Tag = (OsternMärz - 30)) and (Monat = 4))) then writeln(Tag, '.', Monat, '.', Jahr, ' ist gültig und ist Ostermontag.') else writeln(Tag,'.',Monat,'.',Jahr, ' ist gültig und liegt nicht an Ostern.') end else writeln('Den ', Tag, '. gibt es in diesem Monat nicht!'); readln; end else begin writeln('Ungültiges Jahr!'); readln; end else begin writeln('Ungültiger Monat!'); readln; end else begin writeln('Ungültiger Tag!'); readln; end; end. |
AW: Erstellen eines Datum-überprüfers
Hättest Du ein paar Jahreszahlen als Beispiel wo es Probleme gibt? Danke!
(entweder ich bin zu müde oder im von Dir verlinkten Artikel steht nichts darüber...) //edit Ich habe Deinen Code nicht getestet aber einen Vorschlag, diese 3 If's als eins zusammenführen
Delphi-Quellcode:
if (((Tag > 0) and (Tag < 32)) and ((Monat > 0) and (Monat < 13)) and ((Jahr > 0) and (Jahr < 9999))) then
Ach nein, Du wertest diese If's einzeln aus. |
AW: Erstellen eines Datum-überprüfers
Zitat:
Wer es sich selber beigebracht hat, ging eh quer durch. Aber wer es in Schule oder Studium gelernt hat kennt das, Stück für Stück, immer ein bisschen was neues. Und genau darum geht es hier.
Delphi-Quellcode:
Stuktur und Verschachtelung.
IF THEN ELSE
Wer mehr machen will, oder es anders machen will der kann das Privat sicher gerne machen. Aber wenn der Test mit diesen Einschränkungen kommt dann sind die halt so. Grundlagen. Grundlagen. Grundlagen. |
AW: Erstellen eines Datum-überprüfers
Zitat:
Hatte bereits ein entsprechendes Beispiel gepostet und es aufgrund des Hinweises geändert. Zitat:
Was ist bei If then else zu beachten. Welche Fallstricke gibt es bei der Nutzung von AND und OR, wann müssen dort Klammern gesetzt werden, wann nicht (Grundzüge der booleschen Algebra). Das Schaltjahr ist halt ein schöner Aufhänger für sowas, weil man die Richtigkeit der Ergebnisse ohne jegliche Hilfsmittel prüfen kann. Man muss wissen: Jahr durch 4, wenn nicht durch hundert, ausser durch 400. Zitat:
Wenn es morgen heißt: Schön, Ihre Lösung gefällt mir. Nächste Aufgabe: Bitte das Gleiche in C++, Java, Python, Basic, was weiß der Geier ... Was hilft es mir da, wenn in Unit xyz von Delphi schon was fertiges drinne ist? Wenn man die Grundlagen der Programmierung im Studium gelernt hat, unabhängig von irgendeiner Programmiersprache, hat man nach dem Studium eine reellle Chance mit der Programmiersprache zu arbeiten, die beim zukünftigen Arbeitgeber zum Einsatz kommt. Wenn ich virtuos mit Delphi und seinen Units und alle den vielen Feinheiten und Besonderheiten, die wir (mehr oder weniger) alle daran so schätzen, umgehen kann, hilft das herzlich wenig, wenn nachher was völlig anderes zum Einsatz kommt. Aber die Grundlagen, die nach dem Studium sitzen sollten, helfen immer weiter, sie sind überall gleich. |
AW: Erstellen eines Datum-überprüfers
hallo,
'Hättest Du ein paar Jahreszahlen als Beispiel wo es Probleme gibt? Danke!' ich nehme mal an, das ich gemeint war. Laut dem code aus #22 340,360,380,400 usw. Ich wollte nur wie in #5 auf die Kalenderreform von 1582 hinweisen Gruß |
AW: Erstellen eines Datum-überprüfers
Zitat:
|
AW: Erstellen eines Datum-überprüfers
Zitat:
Delphi-Quellcode:
Ein Beispiel:
OsterMonat := 3; // -> März
OsterSonntag := 22 + d + e - 7f; if OsterSonntag > 31 then begin OsterMonat := OsterMonat + 1; // -> April // oder OsterMonat := 4; // aus 22 + d + e - 7f wird 22 + d + e - 7f - 31, da 22 - 31 = -9 wird daraus d + e - 7f - 9 OsterSonntag := OsterSonntag - 31; end; Sei 22 + d + e - 7f = 35, so fiele der Ostersonntag auf den 35. März. Den gibt es nicht. Rechnen wird nun mit 22 + d + e - 7f - 31: Wenn wir das etwas umstellen, wird daraus: d + e - 7f + 22 - 31 Nun rechnen wir noch aus, was 22 - 31 ergibt: -9 und tragen dies in die Formel ein. Damit erhalten wir: d + e - 7f - 9. Prinzipiell gilt also: Ist das Ergebnis von 22 + d + e - 7f größer als 31, so rechnen wir auf den Monat eins drauf -> März + 1 = April und ziehen vom 35. März die 31 Tage des März ab. Damit erhalten wir für den Ostersonntag den 4. April. Im Programm brauchen wird die Formel d + e - 7f - 9 schlicht und einfach nicht. Sie ist bestenfalls irreführende Redundanz ;-) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:21 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz