Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Neuen Beitrag zur Code-Library hinzufügen (https://www.delphipraxis.net/33-neuen-beitrag-zur-code-library-hinzufuegen/)
-   -   Delphi Verbesserte Version von Years-, MonthsBetween + DurationStr (https://www.delphipraxis.net/142396-verbesserte-version-von-years-monthsbetween-durationstr.html)

Sir Rufo 27. Okt 2009 17:01

Re: Verbesserte Version von YearsBetween, MonthsBetween
 
Zitat:

Zitat von Wolfgang Mix
@Sir Rufo

Mir fällt gerade ein, daß ich YearsBeween schon 1992 problemloser ohne Delphi
unter DBase entwickelt habe.
Die Grundidee ist diese

Du findest den Code unter CodeLib/SysUtils2/function Age();

Teste 'mal bitte

Grüß

Wolfgang

Jo, danke,

aber das kann ich nicht benutzen, da ich bei folgenden Vergleichszeiten
'27.10.2009 17:56:16' und
'27.10.2011 17:56:15'
folgendes Ergebnis möchte:
'1 Jahr 11 Monate 4 Wochen 2 Tage 23 Stunden 59 Minuten 59 Sekunden'
Und deine Funktion gibt mir da 2 Jahre aus

Die Himi-Funktion habe ich abgeändert und die liefert genau was ich brauche (ohne Schleife)

cu

Oliver

himitsu 27. Okt 2009 17:01

Re: Verbesserte Version von YearsBetween, MonthsBetween
 
Zitat:

Zitat von Sir Rufo
Die Version ist - es wird nun nicht mehr gerundet - so auch gekauft :mrgreen:

:angel:

Wenn du die Extravariablen (d1 und d2) nimmst, dann kannst du das CONST wieder bei den Parametern einfügen :)
(hatte mir diese zusätzlichen Variablen nur erspart, da Delphi hier, selbst mit CONST nicht call-by-referenz nutzt, sondern auch da beide Parameter auf den Stack schiebt, so als würde kein CONST dastehn ... drum hat man ohne Extravariablen und ohne CONST 16 Byte auf'm Stack eingespart, aber so sehr fällt das nun auch nicht auf :angel2: )


Wenn du die Tageszeit mit beachten willst, dann dürfte eine weitere Zeile nach CheckedSwap dieses wohl ermöglichen
Delphi-Quellcode:
If Trunc(d1) < Trunc(d2) then d2 := d2 + 1;
eventuell auch mit 'nem kleinen Rundunssschutz von ~1 Sekunde
Delphi-Quellcode:
If d2 - d1 >= 0.00001157 {1s} then d2 := d2 + 1;


oder andersrum? :gruebel:
Delphi-Quellcode:
If Trunc(d1) > Trunc(d2) then d2 := d2 - 1;
// bzw.
If d1 - d2 >= 0.00001157 {1s} then d2 := d2 - 1;
mein schädel brummt grad etwas und hab jetzt nicht so den Nerv mir 'nen kleines Testprogrämmchen zu schreiben

Wolfgang Mix 27. Okt 2009 17:11

Re: Verbesserte Version von YearsBetween, MonthsBetween
 
@Sir Rufo
Na dann freue ich mich mit Dir auf Deinen optimierten Code :-D

[Edit] Gerade erst gelesen:
Thus, for example, YearsBetween reports the difference between Jan 1 and Dec 31 as 0 on non-leap years and 1 on leap years.
Allein schon wegen dieser Aussage in der OH ist die Funktion YearsBetween IMHO mangelhaft [/Edit]

Gruß

Wolfgang

Sir Rufo 28. Okt 2009 12:51

Re: Verbesserte Version von Years-, MonthsBetween + Duration
 
Ist ja jetzt egal, jetzt haben wir ja eine genaue Funktion dafür.

Ich habe jetzt aus dem ganzen Geraffel eine Unit gebaut, die als Hauptzweck den Unterschied zwischen zwei Zeitangaben in einer Textform ausgibt.

Auch hier waren noch einige Rundungsfehler aus der DateUtils zu umschiffen.

cu

Oliver

Wolfgang Mix 28. Okt 2009 15:58

Re: Verbesserte Version von Years-, MonthsBetween + Duration
 
Nettes Tool, Deine Demo, Kompliment!

Werde ich gerne für Demonstrationszwecke verwenden :-D

Gruß

Wolfgang

himitsu 28. Okt 2009 17:06

Re: Verbesserte Version von Years-, MonthsBetween + Duration
 
Liste der Anhänge anzeigen (Anzahl: 1)
Mal so aus Interesse ... rechnet dieses wenigstens richtig?
Hach, es war schön das Format-Befehlchen mal wieder etwas mißbrauchen zu "dürfen".

:warn: An die Kinder: Bitte nicht nachmachen :lol:
Delphi-Quellcode:
Uses Math, DateUtils;

Function DurationStr(ANow, AThen: TDateTime): String;
  Var D: TDateTime;
    Yn, Yt, Mn, Mt, Wt, Dn, Dt: Word;
    Hn, Ht, Nn, Nt, Sn, St, Tn, Tt: Word;

  Begin
    If ANow > AThen Then Begin
      D    := ANow;
      ANow := AThen;
      AThen := D;
    End;
    DecodeDate(ANow, Yn, Mn, Dn);
    DecodeDate(AThen, Yt, Mt, Dt);
    DecodeTime(ANow, Hn, Nn, Sn, Tn);
    DecodeTime(AThen, Ht, Nt, St, Tt);
    Tt := Tt - Tn; If SmallInt(Tt) < 0 Then Begin Inc(Tt, 1000); Dec(St); End;
    St := St - Sn; If SmallInt(St) < 0 Then Begin Inc(St, 60);   Dec(Nt); End;
    Nt := Nt - Nn; If SmallInt(Nt) < 0 Then Begin Inc(Nt, 60);   Dec(Ht); End;
    Ht := Ht - Hn; If SmallInt(Ht) < 0 Then Begin Inc(Ht, 24);   Dec(Dt); End;
    Dt := Dt - Dn; If SmallInt(Dt) < 0 Then Begin Inc(Dt,
         DaysInAMonth(Yt + Min(Mt - 2, 0), (Mt + 10) mod 12 + 1)); Dec(Mt); End;
    Wt := Dt div 7; Dt := Dt mod 7;
    Mt := Mt - Mn; If SmallInt(Mt) < 0 Then Begin Inc(Mt, 12);   Dec(Yt); End;
    Yt := Yt - Yn;
    Result := '';
    If Yt > 0 Then Result := Result + Format('%.0n Jahr%*:s ', [Yt / 1, Min(Yt+1,3), '', 'e']);
    If Mt > 0 Then Result := Result + Format('%d Monat%*:s ',  [Mt, Min(Mt+1,3), '', 'e']);
    If Wt > 0 Then Result := Result + Format('%d Woche%*:s ',  [Wt, Min(Wt+1,3), '', 'n']);
    If Dt > 0 Then Result := Result + Format('%d Tag%*:s ',    [Dt, Min(Dt+1,3), '', 'e']);
    If Ht > 0 Then Result := Result + Format('%d Stunde%*:s ', [Ht, Min(Ht+1,3), '', 'n']);
    If Nt > 0 Then Result := Result + Format('%d Minute%*:s ', [Nt, Min(Nt+1,3), '', 'n']);
    If St > 0 Then Result := Result + Format('%d Sekunde%*:s ', [St, Min(St+1,3), '', 'n']);
    If Tt > 0 Then Result := Result + Format('%d msec', [Tt]);
    If Result = '' Then Result := 'gleich' Else Result := Trim(Result);
  End;
[edit] kleinen Fehler behoben ... hatte die Millisekunden vergessen zu berechnen
und ein Tag hat 60 Stunden :oops:

[add] kleines Testprogrammchen angehängt


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:44 Uhr.
Seite 2 von 2     12   

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