Es ist doch auch nicht nötig, für die Berechnung einer Einheit, die enthaltenen
kleineren Einheiten zu kennen. Für die Berechnung der Tage ist es doch auch völlig unwichtig, wie viele Stunden ein Tag hat.
Ermitteln der ganzen Jahre... mit Rest ermitteln wie viele ganze Monate... mit Rest ermitteln wie viele ganze Tage (ab 1. des letzten angebrochenen Monats)... mit Rest ermitteln wie viele ganze Stunden...usw.
Ganz klar, der Monat ist keine Konstante sondern ein variabler Wert... selbst wenn die Monate genau zurückgerechnete werden, lässt sich nur der ganzzahlige Anteil genau bestimmen, der Nachkommawert wäre immer relativ (zu 28,29,30 oder 31 Tagen)
Außerdem das nächste Problem... 2. Januar bis 27 Februar. Ist das Jetzt ein Monat + Tage, auch wenn kein ganzer Monat eingeschlossen ist oder ist das 0 Monate und 57 Tage? Die gleiche Überlegung kommt dann bei "halben" Jahren und Schaltjahren auf.
Genauer Unterschied geht also nur in Tagen und Stunden, größere konstante Einheiten gibt es beim Datum nicht. Monat, Jahr, Jahrhundert sind variable Werte und ungeeignet zum Ausdrücken eines genauen Wertes.
***
1 Km = 1000 m / 1m = 1000mm, das sind Konstante Einheiten
Wäre auf der Autobahn 1 Km = 900m und auf der Landstraße 1 Km = 1100m, dann lies sich die Gesamtstrecke auch nicht genau in km angeben. Man müsste dann sagen x Km Autobahn + y Km Landstraße oder die Strecke in der ersten kontanten Einheit Meter angeben.
***
Mal ein Ansatz, wie ich mir das vorstelle:
Delphi-Quellcode:
function DateTimeStrBetween(StartDT, EndDT : TDateTime):String;
var
Years, Months, Days,
Year1, Month1, Day1,
Year2, Month2, Day2: Word;
begin
DecodeDate(StartDT, Year1, Month1, Day1);
DecodeDate(EndDT, Year2, Month2, Day2);
// Stunden, Minuten etc. darf berechnen wer will
Days := (DateUtils.DaysInAMonth(Year1, Month1)-Day1) + Day2;
// was machen wir mit mehr als 27 Tagen? Monat ist kein konstanter Wert
Months := (12 - Month1) + (Month2 -1);
// Auch hier mehr als 12 Monate möglich, aber Jahr = 12 Monate ist eine Konstante
Years := Year2 - Year1 -1;
if SmallInt(Years) < 0 then Years := 0;
// wer also keine 13 Monate sehen will, auch wenn darin kein ganzes Jahr ist:
// mathematisch logischer wäre aber, nachfolgende Berechnung nicht zu machen
Years := Years + (Months div 12);
Months := Months mod 12;
Result := Format('%d Jahre, %d Monate, %d Tage',[Years, Months, Days]);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption := DateTimeStrBetween(DateTimePicker1.Date, Now);
end;