Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Erstellen eines Datum-überprüfers (https://www.delphipraxis.net/207917-erstellen-eines-datum-ueberpruefers.html)

Mo53 16. Mai 2021 01:32

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.

blawen 16. Mai 2021 03:35

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:

Bitte den Tag eingeben 31
Bitte den Monat eingeben 1
Bitte das Jahr eingeben 2021
Der 31. ist gültig.
31.1.2021 ist unzulässig.
Für mich ist der Code zu sehr verschachtelt und daher mMn sehr Fehleranfällig.
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:
// Ü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);
...
Was meinst Du mit "der Compiler bleibt stehen"?

himitsu 16. Mai 2021 10:03

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: http://docwiki.embarcadero.com/RADSt...al_Style_Guide
https://www.delphipraxis.net/207755-...-erneuert.html



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.

https://www.delphipraxis.net/41047-t...ortgeschr.html
https://de.wikibooks.org/wiki/Progra...:_Der_Debugger

https://www.youtube.com/watch?v=Oyd0ksN8cRs
http://docwiki.embarcadero.com/RADSt...k_zum_Debuggen





Tipp: statt erst
Delphi-Quellcode:
if Tag
und dann jeweils ein CASE, nimm besser erst nur ein CASE und darin dann die IF

Beim ersten Case hast das ELSE vergessen.






Und falls ihr noch irgendwann zum Optiomieren/Verkürzen kommt, dann Delphi-Referenz durchsuchenIsInLeapYear oder gar Delphi-Referenz durchsuchenDaysInMonth / Delphi-Referenz durchsuchenDaysInAMonth.

DieDolly 16. Mai 2021 10:30

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:

an der Fachhochschule

Delphi.Narium 16. Mai 2021 10:43

AW: Erstellen eines Datum-überprüfers
 
Mal aus Spass ein Pascalscript (ohne Verwendung irgendwelcher Datumsfunktionen):
Delphi-Quellcode:
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.
@DieDolly:

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. ;-)

Michael II 16. Mai 2021 11:44

AW: Erstellen eines Datum-überprüfers
 
Verwende System.SysUtils.EncodeDate( ) und reagiere auf Exceptions. Da lernst du fast mehr ;-)...

Delphi.Narium 16. Mai 2021 11:53

AW: Erstellen eines Datum-überprüfers
 
Frage: Geht es darum Delphi zu lernen oder darum die Grundlagen der Kalenderberechnung zu lernen?

Mo53 16. Mai 2021 12:23

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.

DieDolly 16. Mai 2021 12:34

AW: Erstellen eines Datum-überprüfers
 
Zitat:

und dürfen wir somit auch noch nicht verwenden.
So eine Fachhochschule, die die Schüler scheinbar systematisch auf niedrigem Niveau hält, würde ich sofort verlassen.
Wäre ich dort, würde ich alles verwenden, was ich kenne, und nicht das, was ich darf.

venice2 16. Mai 2021 12:54

AW: Erstellen eines Datum-überprüfers
 
Delphi-Quellcode:
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.
Habe mir erlaubt den Quelltext zu formatieren und im Delphi Tag einzubetten. (Aber nichts getestet oder daran verändert.)
@DieDolly! Helfe ihm doch einfach als über ihn herzuziehen er kann nichts für die Vorschriften die man ihm auferlegt.

Just my 2 Cent!

DieDolly 16. Mai 2021 12:55

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.

himitsu 16. Mai 2021 12:55

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.

Mo53 16. Mai 2021 13:05

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.

mmw 16. Mai 2021 13:06

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.

DieDolly 16. Mai 2021 13:12

AW: Erstellen eines Datum-überprüfers
 
Zitat:

jetzt besteht aber das Problem das das Programm nach der Abfrage des Datums endet.
Ich habe im ganzen Thread bisher nicht einen Kommentar gesehen, wo der Delphi Style Guide auch nur annähernd respektiert wird.
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!

Delphi.Narium 16. Mai 2021 13:25

AW: Erstellen eines Datum-überprüfers
 
Nochmal einen Abschnitt überarbeitet:
Delphi-Quellcode:
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;
@DieDolly
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 ;-)

Mo53 16. Mai 2021 15:58

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.

Delphi.Narium 16. Mai 2021 16:08

AW: Erstellen eines Datum-überprüfers
 
Suchmaschine marsch: ostern formel
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.

himitsu 16. Mai 2021 16:19

AW: Erstellen eines Datum-überprüfers
 
Zitat:

Zitat von Mo53 (Beitrag 1489579)
Wenn ihr noch einen Fehler entdeckt könnt Ihr mich gerne darauf hinweisen.

Monat 2 und darin vom If das Else.

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:
if (Tag <= 29) then
macht, wenn der Tag 30 oder 31 ist.



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)

TBx 16. Mai 2021 16:55

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.

himitsu 16. Mai 2021 17:11

AW: Erstellen eines Datum-überprüfers
 
Zitat:

Delphi-Quellcode:
if (Monat >= 1) and (Monat <= 12) then begin

Warum nicht als ELSE im Case?

Mo53 16. Mai 2021 17:30

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.

TBx 16. Mai 2021 17:54

AW: Erstellen eines Datum-überprüfers
 
Zitat:

Zitat von himitsu (Beitrag 1489584)
Zitat:

Delphi-Quellcode:
if (Monat >= 1) and (Monat <= 12) then begin

Warum nicht als ELSE im Case?

Hätte man machen können, dann hätte man halt die bestehende Else in ein case für 4,6,9,11 umwandeln müssen.

KodeZwerg 16. Mai 2021 17:58

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 (Delphi-Referenz durchsuchenEncodeDate sollte da Wunder wirken).

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!

Delphi.Narium 16. Mai 2021 18:17

AW: Erstellen eines Datum-überprüfers
 
Zum Spaß noch ein Ansatz:
Delphi-Quellcode:
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.
@KodeZwerg:

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 ;-)

venice2 16. Mai 2021 18:29

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.

DieDolly 16. Mai 2021 18:44

AW: Erstellen eines Datum-überprüfers
 
Bei diesem ganzen Case true false werfe ich mal IfThen in den Raum.

venice2 16. Mai 2021 18:47

AW: Erstellen eines Datum-überprüfers
 
Zitat:

Zitat von DieDolly (Beitrag 1489590)
Bei diesem ganzen Case true false werfe ich mal IfThen in den Raum.

Warum? Um dann diesen ganzen IFThen Kram zu haben? Wo soll da der Vorteil liegen.

tsss..

mmw 16. Mai 2021 19:44

AW: Erstellen eines Datum-überprüfers
 
hallo,

zur Erinnerung

https://www.geo.de/geolino/mensch/25...der-29-februar
:-D

wurde aber schon drauf hingewiesen #5

Gruß

Mo53 16. Mai 2021 20:15

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.

Mo53 16. Mai 2021 20:37

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.

KodeZwerg 16. Mai 2021 23:46

AW: Erstellen eines Datum-überprüfers
 
Zitat:

Zitat von Mo53 (Beitrag 1489595)
Delphi-Quellcode:
a, b, c, d, e, f: integer;

Und was bedeuten diese Variablen-Namen??? Gewöhne es dir bitte ab das so zu schreiben, die Mitglieder hier würden es dir danken!

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.

Mo53 17. Mai 2021 00:29

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 https://praxistipps.focus.de/ostern-...D%20d%2Be-7f-9.
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.

KodeZwerg 17. Mai 2021 00:53

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.

Sinspin 17. Mai 2021 07:31

AW: Erstellen eines Datum-überprüfers
 
Zitat:

Zitat von KodeZwerg (Beitrag 1489587)
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?

Für die einen oder anderen ist es wohl schon ein bisschen länger her programmieren gelernt zu haben.
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:
IF THEN ELSE
Stuktur und Verschachtelung.
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.

Delphi.Narium 17. Mai 2021 16:40

AW: Erstellen eines Datum-überprüfers
 
Zitat:

Zitat von DieDolly (Beitrag 1489590)
Bei diesem ganzen Case true false werfe ich mal IfThen in den Raum.

Weiter oben steht aber, dass Funktionen nicht genutzt werden sollen.

Hatte bereits ein entsprechendes Beispiel gepostet und es aufgrund des Hinweises geändert.
Zitat:

Zitat von Mo53
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.

Exakt darum geht es: Lernen, wie man Probleme löst, für die es noch keine fertige Lösung (Funktion, Prozedur, ...) gibt.

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:

Zitat von Sinspin
Für die einen oder anderen ist es wohl schon ein bisschen länger her programmieren gelernt zu haben.
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. IF THEN ELSE Stuktur und Verschachtelung.
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.

Genau das ist es: Es geht darum Programmieren zu lernen und nicht darum den Umgang und die Besonderheiten von Delphi zu lernen.

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.

mmw 17. Mai 2021 19:24

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ß

Benmik 17. Mai 2021 19:45

AW: Erstellen eines Datum-überprüfers
 
Zitat:

Zitat von DieDolly (Beitrag 1489571)
So eine Fachhochschule, die die Schüler scheinbar systematisch auf niedrigem Niveau hält, ...

Soso, Kulturkritik, aber dann den Unterschied zwischen "scheinbar" und "anscheinend" nicht kennen... Wenn die Schule die Schüler nur scheinbar auf niedrigem Niveau hält, dann ist ja alles bestens.

Delphi.Narium 17. Mai 2021 20:54

AW: Erstellen eines Datum-überprüfers
 
Zitat:

Zitat von Mo53 (Beitrag 1489595)
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.

Die Formulierung ist vielleicht etwas unglücklich. Gemeint ist schlicht und einfach:
Delphi-Quellcode:
  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;
Ein Beispiel:

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 01:12 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz