AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Datumsdifferenz berechnen?

Ein Thema von ThaiSon96 · begonnen am 19. Jan 2014 · letzter Beitrag vom 23. Jan 2014
Antwort Antwort
Seite 3 von 3     123   
nahpets
(Gast)

n/a Beiträge
 
#21

AW: Datumsdifferenz berechnen?

  Alt 21. Jan 2014, 00:45
Hatte gerade mal ein bisserl Langeweile und das ist dabei rausgekommen:
Delphi-Quellcode:
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.
Natürlich lässt sich da noch so einiges zusammenfassen und verschöneren...
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
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#22

AW: Datumsdifferenz berechnen?

  Alt 21. Jan 2014, 07:09
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;
  Mit Zitat antworten Zitat
Benutzerbild von baumina
baumina

Registriert seit: 5. Mai 2008
Ort: Oberschwaben
1.275 Beiträge
 
Delphi 11 Alexandria
 
#23

AW: Datumsdifferenz berechnen?

  Alt 21. Jan 2014, 07:17
Was ist denn, wenn ich mehr als 1 Jahr zwischen den beiden Datumsen habe?
Mehr als ein Jahr liegt eh nie zwischen den Ferien
Hinter dir gehts abwärts und vor dir steil bergauf ! (Wolfgang Ambros)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.068 Beiträge
 
Delphi 12 Athens
 
#24

AW: Datumsdifferenz berechnen?

  Alt 21. Jan 2014, 11:00
Mehr als ein Jahr liegt eh nie zwischen den Ferien
In der Überschrift ist aber nicht nur von Ferien die Rede.

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 Result := Result + ... an den Anfang der Schleife, bevor dort der Monat erhöt wird

Oder die Schleife muß einen Monat früher aufhören, also noch mal die Abbruchbedingung (mit if then break; ) nach dem Erhöhen des Monats, bevor Addiert wird.

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 (Result := -Result; )
- erkennen, austauschen, -1 oder 1 merken und am Ende damit multiplizieren
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (21. Jan 2014 um 11:09 Uhr)
  Mit Zitat antworten Zitat
ThaiSon96

Registriert seit: 7. Mai 2013
11 Beiträge
 
Delphi 7 Personal
 
#25

AW: Datumsdifferenz berechnen?

  Alt 22. Jan 2014, 20:04
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.
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#26

AW: Datumsdifferenz berechnen?

  Alt 22. Jan 2014, 21:19
Sehr gut!
Aber was ist, wenn das Jahr kein Schaltjahr ist?
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#27

AW: Datumsdifferenz berechnen?

  Alt 22. Jan 2014, 21:24
Ich glaub aber die While-Schleife ist falsch, denn dort wird scheinbar ein Monat zu viel eingerechnet.
- vor der Schleife den Monat erhöhen
Jupp, aber mehr muss nicht sein, oder?. War ja nur ne Idee in Delphi#.
Die ganzen Abfragen kann man noch einbauen, aber ich mach ja nicht alle Hausarbeiten.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#28

AW: Datumsdifferenz berechnen?

  Alt 22. Jan 2014, 22:10
Es ist noch ein Fehler in der Gültigkeitsabfrage
Code:
Heute: [FerienTag+x].[FerienMonat].[FerienJahr]
Also gleiches Jahr, gleicher Monat und der heutige Tag größer als der Ferientag
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
bcvs

Registriert seit: 16. Jun 2011
703 Beiträge
 
Delphi 12 Athens
 
#29

AW: Datumsdifferenz berechnen?

  Alt 23. Jan 2014, 08:02
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.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 3     123   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:28 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