Calculer somme et moyenne de durées exprimées en minutes, secondes, centièmes

Soyez le premier à donner votre avis sur cette source.

Vue 20 998 fois - Téléchargée 562 fois

Description

Le Format est mm:ss:cc.

Fonctions que l'on peut aisément adapter pour d'autres usages, ou étendre (calcul des heures si minutes > 60, voire des jours, après faut voir, lol).

En réponse à cette question du forum :

http://www.delphifr.com/forum.v2.aspx?ID=467096

En espérant que ça pourra être utile à d'autres.

Merci à WhiteHippo pour m'avoir fait remarquer que mon code précédent ne respectait pas le contrat énoncé dans l'intitulé du titre.
J'avais en effet annoncé une fonction calculant la moyenne, et envoyé une fonction calculant la somme !
D'où la mise à jour...

J'ai laissé la fonction précédente que j'ai renommée de manière plus judicieuse.

Un exemple d'utilisation se trouve dans le zip.

Je n'ai pas mis de commentaires, mais n'hésitez pas à me demander une explication.

Bonne prog' :p


Mise à jour du 28 mai 2005

J'ai rajouté une autre manière de procéder.

Le but étant d'éviter la redondance des calculs entre les deux méthodes.

La difficulté que j'ai rencontrée a été la prise en charge des chaines vides, non considérées comme invalides, mais ne devant pas être prises en compte dans le calcul de la moyenne.
Les chaînes vides sont donc admises, qu'elles se trouvent à la fin, au début, ou insérées dans la liste.

J'espère avoir rempli le contrat. :)

Mais cette approche me semble un poil plus complexe...
Je laisse donc la première version, qui reste valable si l'on prend chaque fonction séparément, et dont la compréhension est plus immédiate.

Le zip lui-même contient les deux versions : Old et New.

Bonne prog' :p

Source / Exemple :


{ PREMIERE MANIERE }

function CalculeSomme(tS: TStrings): String;
var i: Integer;
    Minutes, Secondes, Centiemes: Integer;
    STmp: String;
begin
  Result := '';
  Minutes := 0;
  Secondes := 0;
  Centiemes := 0;
  for i := 0 to tS.Count -1 do
  begin
    STmp := tS[i];
    if STmp = '' then Break;
    try
      Minutes := Minutes + StrToInt(Copy(STmp, 1, Pos(':', STmp) -1));
      Delete(STmp, 1, Pos(':', STmp));
      Secondes := Secondes + StrToInt(Copy(STmp, 1, Pos(':', STmp) -1));
      Delete(STmp, 1, Pos(':', STmp));
      Centiemes := Centiemes  + StrToInt(STmp);
    except
      ShowMessage(tS[i] + ' n''est pas un format valide');
      Exit;
    end;
  end;
  Secondes := Secondes + Centiemes div 100;
  Centiemes := Centiemes mod 100;
  Minutes := Minutes + Secondes div 60;
  Secondes := Secondes mod 60;
  Result := Format('%.2d:%.2d:%.2d', [Minutes, Secondes, Centiemes]);
end;

function CalculeMoyenne(tS: TStrings): String;
var i: Integer;
    Minutes, Secondes, Centiemes: Integer;
    StringsValides: Integer;
    STmp: String;
begin
  Result := '';
  StringsValides := 0;
  Centiemes := 0;
  for i := 0 to tS.Count -1 do
  begin
    STmp := tS[i];
    if STmp = '' then Break;
    try
      Inc(StringsValides);
      Minutes := StrToInt(Copy(STmp, 1, Pos(':', STmp) -1));
      Delete(STmp, 1, Pos(':', STmp));
      Secondes := StrToInt(Copy(STmp, 1, Pos(':', STmp) -1));
      Delete(STmp, 1, Pos(':', STmp));
      Centiemes :=    Centiemes
                    + StrToInt(STmp)
                    + Secondes * 100
                    + Minutes * 6000; // 60 * 100
    except
      ShowMessage(tS[i] + ' n''est pas un format valide');
      Exit;
    end;
  end;
  Centiemes := Centiemes div StringsValides;
  Secondes := Centiemes div 100;
  Centiemes := Centiemes mod 100;
  Minutes := Secondes div 60;
  Secondes := Secondes mod 60;
  Result := Format('%.2d:%.2d:%.2d', [Minutes, Secondes, Centiemes]);
end;

{---------------------------------------------------------------}

{ DEUXIEME MANIERE }

{ La valeur retournée correspond au nombre de Strings valides, 0 si erreur }
function CalculeSommeInt(var Min, Sec, Cent: Integer; tS: TStrings): Integer;
var i: Integer;
    STmp: String;
begin
  Result := 0;
  Min := 0;
  Sec := 0;
  Cent := 0;
  for i := 0 to tS.Count -1 do
  begin
    STmp := tS[i];
    if STmp = '' then Continue;
    try
      Inc(Result);
      Min := Min + StrToInt(Copy(STmp, 1, Pos(':', STmp) -1));
      Delete(STmp, 1, Pos(':', STmp));
      Sec := Sec + StrToInt(Copy(STmp, 1, Pos(':', STmp) -1));
      Delete(STmp, 1, Pos(':', STmp));
      Cent := Cent  + StrToInt(STmp);
    except
      ShowMessage(tS[i] + ' n''est pas un format valide');
      Result := 0;
      Exit;
    end;
  end;
  Sec := Sec + Cent div 100;
  Cent := Cent mod 100;
  Min := Min + Sec div 60;
  Sec := Sec mod 60;
end;

{ La valeur retournée est True si la fonction aboutit }
function CalculeMoyenneInt(var Min, Sec, Cent: Integer; tS: TStrings): Boolean;
var StringsValides: Integer;
begin
  Result := False;
  StringsValides := CalculeSommeInt(Min, Sec, Cent, tS);
  if StringsValides > 0 then
  begin
    Cent := Cent + Sec * 100 + Min * 6000;
    Cent := Cent div StringsValides;
    Sec := Cent div 100;
    Cent := Cent mod 100;
    Min := Sec div 60;
    Sec := Sec mod 60;
    Result := True;
  end
end;

{ Renvoie une chaîne correspondant à la somme, au format mm:ss:cc }
function CalculeSommeStr(tS: TStrings): String;
var Minutes, Secondes, Centiemes: Integer;
begin
  Result := '';
  if CalculeSommeInt(Minutes, Secondes, Centiemes, tS) > 0 then
    Result := Format('%.2d:%.2d:%.2d', [Minutes, Secondes, Centiemes]);
end;

{ Renvoie une chaîne correspondant à la moyenne, au format mm:ss:cc }
function CalculeMoyenneStr(tS: TStrings): String;
var Minutes, Secondes, Centiemes: Integer;
begin
  Result := '';
  if CalculeMoyenneInt(Minutes, Secondes, Centiemes, tS) then
    Result := Format('%.2d:%.2d:%.2d', [Minutes, Secondes, Centiemes]);
end;

Conclusion :


Fait sous Delphi 4, et compatible toute version 32 bits, normalement ;)

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

orankader
Messages postés
4
Date d'inscription
lundi 22 août 2005
Statut
Membre
Dernière intervention
29 décembre 2009
-
Bonjour tous le monde
j'ai un probmème dans mon programme, je n'arrive pas à calculer un total heure avec mon programme le calcul
se fait très bien, mais une fois il dépasse les 24 heures sa remis à 00:00.
Pour cela si quelqu'un peut m'aider en corrigeant mon programme



procedure TForm1.Button3Click(Sender: TObject);
var somme,s : real;

begin
somme := 0;
table1.first; // se pointer vers le premier enregistrement de la table
while not(table1.eof) do // tanque on a pas arriver à la fin de la table
begin
somme := somme + table1.fieldbyname('Nbre_Heures').AsDateTime; // cumul des totaux
table1.next; // passer à l’enregistrement suivant.
end;
edit1.text := TimeToStr(somme); // afficher le cumul des totaux dans le comosant edit1

end;
japee
Messages postés
1706
Date d'inscription
vendredi 27 décembre 2002
Statut
Modérateur
Dernière intervention
7 juillet 2019
-
Tiens, ça faisait un bail, JMP77... ça va, toi ?

"Tu trouves toujours des sujets de sources très interessants et enrichissants merci à toi"

Ben alors là, ça, ça fait plaisir...

Dorénavant, JMP77, je posterai plus que pour toi, lol ;-)

Et un coucou amical à Mauricio qui m'a fait l'honneur de venir faire un tour sur mon source, muito obrigado ;-)

Bonne prog' :p

japee
jmp77
Messages postés
1232
Date d'inscription
lundi 4 février 2002
Statut
Membre
Dernière intervention
4 octobre 2006
4 -
Hello Japee,

Comme tu l'as si bien sugérer j'ai modifié ta fonction de calcul de la somme en utilisant DecodeTime et EncodeTime la voici :

function TForm1.CalculeSommeInt2(var Min, Sec, Cent: Integer; tS: TStrings): Integer;
var i: Integer;
STmp: String;
Totale : TDateTime;

begin
Result := 0;
Min := 0;
Sec := 0;
Cent := 0;
Totale := 0;

for i := 0 to tS.Count -1 do
begin
STmp := tS[i];

if STmp = '' then Continue;

try
Inc(Result);
Min := StrToInt(Copy(STmp, 1, Pos(':', STmp) -1));
Delete(STmp, 1, Pos(':', STmp));
Sec := StrToInt(Copy(STmp, 1, Pos(':', STmp) -1));
Delete(STmp, 1, Pos(':', STmp));
Cent := StrToInt(STmp);
Totale := Totale + EncodeTime(0,Min,Sec,Cent);
except
ShowMessage(tS[i] + ' n''est pas un format valide');
Result := 0;
Exit;
end;
end;

ShowMessage(FormatDateTime('nn:ss:z',Totale));
end;

Voila sinon je pense que je laisserai les deux car cela permet de voir comment s'effectue le calcul des heures avec les minutes, les secondes et les centiemes. Avec ta methode on comprend bien le fonctionnement avec encodetime c'est sur ça simplifie la fonction mais c'est moins instructif je trouve.

Tu trouves toujours des sujets de sources très interessants et enrichissants merci à toi.

Allez ca merite un bon 9/10 pour moi à cette source.

Bonne prog,
JMP77.
cs_MAURICIO
Messages postés
2233
Date d'inscription
mardi 10 décembre 2002
Statut
Modérateur
Dernière intervention
15 décembre 2014
5 -
Salut Japee et bonjour tout le monde en fait...
Pour répondre à DeltaX tu peux faire toute sorte d' operation mathematique avec les TDatetimes (soustraction etc...).
DeltaFX
Messages postés
459
Date d'inscription
lundi 19 avril 2004
Statut
Membre
Dernière intervention
8 avril 2009
1 -
Y a pas des fonctions déja présentes dans delphi pour jouer avec les heures ?

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.