Einzelnen Beitrag anzeigen

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