![]() |
AW: Datumsdifferenz berechnen?
Hatte gerade mal ein bisserl Langeweile und das ist dabei rausgekommen:
Delphi-Quellcode:
Natürlich lässt sich da noch so einiges zusammenfassen und verschöneren...
program Project1;
{$APPTYPE CONSOLE} uses SysUtils, DateUtils; type tDatum = record Tag: 1..31; Monat: 1..12; Jahr: 2014..maxint; end; // of record // Tabelle für die Aufnahme der Anzahl der Tage pro Monat. type tMonate = Array [1..12] of byte; // Ein Schaltjahr ist jedes Jahr, das ohne Rest durch 4 teilbar ist. // Keine Regel ohne Ausnahme: // 1. Ausnahme: Es ist kein Schaltjahr, wenn es durch 100 ohne Rest teilbar ist. // 2. Ausnahme = 1. Ausnahme von 1. Ausnahme: // Es ist ein Schaltjahr, wenn es durch 400 ohne Rest teilbar ist. function IstSchaltjahr(jahr : Integer) : Byte; begin if jahr mod 400 = 0 then Result := 1 else if jahr mod 100 = 0 then Result := 0 else if jahr mod 4 = 0 then Result := 1 else Result := 0; end; function tagebisferien (datumheute, datumferienbeginn: tDatum): integer; var i : Integer; Summe : Integer; JahresDifferenz : Integer; MonateHeute : tMonate; MonateFerien : tMonate; ResttageHeute : Integer; begin // Tabelle mit den monatlichen Tageszahlen für das Jahr zu Heute. MonateHeute[1] := 31; MonateHeute[2] := 28 + IstSchaltjahr(datumheute.Jahr); MonateHeute[3] := 31; MonateHeute[4] := 30; MonateHeute[5] := 31; MonateHeute[6] := 30; MonateHeute[7] := 31; MonateHeute[8] := 31; MonateHeute[9] := 30; MonateHeute[10] := 31; MonateHeute[11] := 30; MonateHeute[12] := 31; // Tabelle mit den monatlichen Tageszahlen für das Jahr des Ferienbeginns. MonateFerien[1] := 31; MonateFerien[2] := 28 + IstSchaltjahr(datumFerienBeginn.Jahr); MonateFerien[3] := 31; MonateFerien[4] := 30; MonateFerien[5] := 31; MonateFerien[6] := 30; MonateFerien[7] := 31; MonateFerien[8] := 31; MonateFerien[9] := 30; MonateFerien[10] := 31; MonateFerien[11] := 30; MonateFerien[12] := 31; // Restliche Tage bis zum Ende des aktuellen Monats berechnen. ResttageHeute := MonateHeute[datumheute.Monat] - datumheute.Tag; // Summe der Tage berechnen. Summe := 0; // Das heutige Datum und das Datum des Ferienbeginns liegen im gleichen Jahr: if datumheute.Jahr = datumferienbeginn.Jahr then begin // Sind Heute und Ferienbeginn im gleichen Monat? if datumheute.Monat = datumferienbeginn.Monat then begin // Dann benötigen wir nur die Differenz zwischen Ferienbeginn und heute, // dabei gilt der angegebene Tag als Teil der Ferien, wir dürfen // also nur bis zum Tag davor rechnen. Summe := datumferienbeginn.Tag - datumheute.Tag - 1; end else begin // Andernfalls: // Zuerst die restlichen Tage des Monats zu Heute: Summe := Summe + ResttageHeute; // Tage vom Folgemonat bis zum Monat vor dem Ferienbeginn berechnen. for i := datumheute.Monat + 1 to datumferienbeginn.Monat - 1 do begin Summe := Summe + MonateHeute[i]; end; // Die Tage des Monates, in den der Ferienbeginn fällt hinzurechnen, // dabei gilt der angegebene Tag als Teil der Ferien, wir dürfen // also nur bis zum Tag davor rechnen. Summe := Summe + datumferienbeginn.Tag - 1; end; end else begin // Der Ferienbeginn liegt im Folgejahr oder später: // Zuerst die restlichen Tage des Monats zum heutigen Datum: Summe := Summe + ResttageHeute; // Die Tage ab dem nächsten Monat bis zum Jahresende berechnen: for i := datumheute.Monat + 1 to 12 do begin Summe := Summe + MonateHeute[i]; end; // Wieviele Jahre liegen zwischen Heute und dem Ferienbeginn? JahresDifferenz := datumferienbeginn.Jahr - datumheute.Jahr; if JahresDifferenz > 1 then begin // Für alle Jahre zwischen Heute und Ferienbeginn // 365 + ggls. 1 für das Schaltjahr addieren: for i := datumheute.Jahr + 1 to datumferienbeginn.Jahr - 1 do begin Summe := Summe + 365 + IstSchaltjahr(i); end; end; // Die Tage vom 1.1. bis zum Monat vor dem Ferienbeginn addieren: for i := 1 to datumferienbeginn.Monat - 1 do begin Summe := Summe + MonateFerien[i]; end; // Und nun noch die Tage des Monats in den der Ferienbeginn fällt // bis zum Tag vor dem Ferienbeginn. Summe := Summe + datumferienbeginn.Tag - 1; end; Result := Summe; end; var heute, ferien: tDatum; anzahl: integer; begin writeln('[= Heutiges Datum =]'); write('Tag: '); readln(heute.Tag); write('Monat: '); readln(heute.Monat); write('Jahr: '); readln(heute.Jahr); writeln('[= Feriendatum =]'); write('Tag: '); readln(ferien.Tag); write('Monat: '); readln(ferien.Monat); write('Jahr: '); readln(ferien.Jahr); Anzahl := tagebisferien(heute, ferien); writeln('Es ist/sind noch ',abs(anzahl),' Tag/Tage bis zu den naechsten Ferien.'); WriteLn; // Gegenprobe per Datumsberechnung mit "Delphi-Mitteln": // Die Gegenprobe funktioniert allerdings "nur" bis zum 31.12.9999, // danach können Fehler auftreten (negativ Anzahl von Tagen) // oder die Anzahl der Tage wird deutlich zu klein angegeben ;-) WriteLn(Format('Gegenprobe mit Datumsroutinen: %d',[Trunc( StrToDateTime(Format('%d.%d.%d',[ferien.Tag,ferien.Monat,ferien.Jahr])) - StrToDateTime(Format('%d.%d.%d',[heute.Tag,heute.Monat,heute.Jahr])) - 1)])); readln; end. aber so als Idee für's erste Lernen könnte es ja unter Umständen eventuell vielleicht hilfreich sein und wenn auch nur als abschreckendes Beispiel ;-) |
AW: Datumsdifferenz berechnen?
Was ist denn, wenn ich mehr als 1 Jahr zwischen den beiden Datumsen habe?
Also ich würde das dann so machen (ungetestet):
Delphi-Quellcode:
Function IstEinSchaltjahr(jahr : Integer) : Bool;
begin if jahr mod 400 = 0 then Result := 1 else if jahr mod 100 = 0 then Result := 0 else if jahr mod 4 = 0 then Result := 1 else Result := 0; end; Function TageImMonat (Monat, Jahr : Integer) : Integer; Begin Case Monat of 1,3,5,7,8,10,12 : Result := 31; 4,6,8,10 : Result := 30; 2 : If IstEinSchaltHahr(Jahr) then Result := 29 else Result := 28; end end; Function AnzahlTage (A,B : TDatum) : Integer; Begin If (A.Jahr=B.Jahr) and (A.Monat=B.Monat) then result := B.Tag - A.Tag; exit; end; L := A; // 1. Alle Tage bis zum Monatsende... Result := TageImMonat(L.Monat, L.Jahr) - A.Tage; // 2. Dann alle Monate bis zum Ferienbeginn zusammenzählen While (L.Jahr<>B.Jahr) and (L.Monat <> B.Monat) Do Begin if L.Monat=12 then begin L.Jahr := L.Jahr +1 ; L.Monat := 1; end else L.Monat := L.Monat + 1; Result := Result + TageImMonat(L.Monat, L.Jahr); end; // 3. Zum Schluss noch die Tage vom Ferienmonat Result := Result + B.Tage; End; |
AW: Datumsdifferenz berechnen?
Zitat:
|
AW: Datumsdifferenz berechnen?
Zitat:
Ich glaub aber die While-Schleife ist falsch, denn dort wird scheinbar ein Monat zu viel eingerechnet. - vor der Schleife den Monat erhöhen - und das
Delphi-Quellcode:
an den Anfang der Schleife, bevor dort der Monat erhöt wird
Result := Result + ...
Oder die Schleife muß einen Monat früher aufhören, also noch mal die Abbruchbedingung (mit
Delphi-Quellcode:
) nach dem Erhöhen des Monats, bevor Addiert wird.
if then break;
PS: Warum BOOL (Integer) und nicht Boolean (Byte und der Standardtyp im Delphi) ? PPS: Warum Integer Zahlen als Result, obwohl es Boolean sein sollten? Notfalls sollte man auch B vor A abfangen, denn sonnst läuft deine Schleife ein Weilchen. (Byte+Integer = bis zu 1.099.511.627.775 Durchläufe) - Dieses erkennen und eine Exception werfen - Dieses erkennen und einen "Fehler"-Wert zurückgeben (z.B. -1 oder MinInt) - Dieses erkennen, die Werte austauschen, das Minus merken und am Ende das Result umdrehen (
Delphi-Quellcode:
)
Result := -Result;
- erkennen, austauschen, -1 oder 1 merken und am Ende damit multiplizieren |
AW: Datumsdifferenz berechnen?
Habe das Programm inzwischen geschafft
Delphi-Quellcode:
program Project2;
{$APPTYPE CONSOLE} uses SysUtils; type tMonat = array [1..12] of integer; tDatum = record Tag: 1..31; Monat: 1..12; Jahr: 2014..maxint; end; // of record var heute, ferien: tDatum; monate : tmonat = (31,29,31,30,31,30,31,31,30,31,30,31); tage: integer; function tagebisferien (datumheute, datumferienbeginn: tDatum): integer; var verbleibendetage: integer; begin verbleibendetage := 0; if datumheute.monat <> datumferienbeginn.Monat then begin verbleibendetage := verbleibendetage + (monate[datumheute.monat] - datumheute.Tag); datumheute.monat :=datumheute.monat +1; while (datumheute.Monat <> datumferienbeginn.monat) do begin verbleibendetage := verbleibendetage + (monate[datumheute.Monat]); datumheute.monat := datumheute.monat +1; end; verbleibendetage := verbleibendetage + datumferienbeginn.tag; end else verbleibendetage := datumferienbeginn.tag - datumheute.tag; result := verbleibendetage; end; begin writeln('[= Heutiges Datum =]'); write('Tag: '); readln(heute.Tag); write('Monat: '); readln(heute.Monat); write('Jahr: '); readln(heute.Jahr); writeln('[= Feriendatum =]'); write('Tag: '); readln(ferien.Tag); write('Monat: '); readln(ferien.Monat); write('Jahr: '); readln(ferien.Jahr); if (heute.Tag > ferien.Tag) AND (heute.Monat > ferien.Monat) AND (heute.Jahr = ferien.Jahr) then writeln('Ungueltige Angaben!') else begin tage := tagebisferien(heute, ferien); writeln('Es ist/sind noch ',abs(tage),' Tag/Tage bis zu den naechsten Ferien'); end; readln; end. |
AW: Datumsdifferenz berechnen?
Sehr gut!
Aber was ist, wenn das Jahr kein Schaltjahr ist? |
AW: Datumsdifferenz berechnen?
Zitat:
Die ganzen Abfragen kann man noch einbauen, aber ich mach ja nicht alle Hausarbeiten. |
AW: Datumsdifferenz berechnen?
Es ist noch ein Fehler in der Gültigkeitsabfrage
Code:
Also gleiches Jahr, gleicher Monat und der heutige Tag größer als der Ferientag :)
Heute: [FerienTag+x].[FerienMonat].[FerienJahr]
|
AW: Datumsdifferenz berechnen?
In deiner while-Schleife zählst du die Monate hoch. Da wird aber ein Jahreswechsel nicht berücksichtigt. Überleg mal, was passiert, wenn du am 31.12 wissen willst, viele Tage es noch bis zu den Faschingsferien sind.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:29 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