Delphi calcul de nombre de jours

Résolu/Fermé
guigui265 Messages postés 113 Date d'inscription mercredi 29 novembre 2000 Statut Membre Dernière intervention 16 avril 2006 - 13 janv. 2006 à 16:06
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 - 16 janv. 2006 à 19:50
Bonjour a tous
J'ai créer un formulaire avec deux datetimepicker, un pour saisir la date de début, et un la date de fin, il y a ensuite un label d'affichage du calcul du nombre de jours ormis le samedi et le dimanche sur le click du bouton calculer.
je n'arrive pas à traiter la manipulation des dates, meme en date to str et date to int, et je n'arrive également pas a traiter le fait de ne pas tenir compte du week end dans le compteur.
Aidez moi!
merci

3 réponses

f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
14 janv. 2006 à 20:50
{YODA+}

Nombreuses fonctions qui te permettrons de faire cela il y as.
Largement commentée dans l'aide delphi elles sont.

uses DateUtils,Math;

function IsWeekDay(const DT : TDateTime): boolean;

{
De savoir si la date "DT" correspond a un jours du weekend (samedi ou dimanche) cette fonction permet.
Attention tu dois faire : contrairement a la fonction DayOfWeek; comme le premier jours de la semaine, Lundi DayOfTheWeek considere.
}
begin
case DayOfTheWeek(DT) of
6,7 : result := true;
else result := false;
end;
end;

function AllDaysBetween(const DFrom,DTo : TDateTime; const ExcludeWE : boolean = false) : integer;

{
Calculer le nombre de jours de la date DFrom a la date DTo, et d'exlure les weekends (ExcludeWE a true doit etre) cette fonction sert.

De stocker la plus petite et la plus grande date selon DFrom et DTo, les variables locales DMin et DMax nous servent.

De savoir laquelle de DFrom et DTo est la plus petite et la plus grande des dates, les fonction Min et Max de l'unité Math, permettent.

Mettre a zero la portion "time" d'une variable de type TDateTime la fonction DateOf de l'unité DateUtils, permet.

Pour plus de performance, la fonction WeekSpan (qui renvois le nombre de semaine entre DMin et DMax) utiliser j'ai; pour dans le calcul exclure les WeekEnd on puissent.
(pour calculer le nombre de jours (hors weekend) du 1er janvier 2000 au 31 decembre de l'an 3000 environ 32 a 47ms il faut.)
}
var DMin,DMax : TDateTime;
begin
DMin := DateOf(Min(DFrom,DTo));
DMax := DateOf(Max(DFrom,DTo));
Result := trunc(DaySpan(DMin,DMax))+1;

if ExcludeWe then begin
result := result - (trunc(WeekSpan(DMin,DMax)*2)+1);
end;
end;

procedure AllDaysBetweenProc(out DaysCount : integer; const DFrom,DTo : TDateTime; const ExcludeWE : boolean = false);

{
A la fonction AllDaysBetween cette procedure est identique.
L'utilisation du parametre OUT plutot que VAR vous devez remarquez.
}
var DMin,DMax : TDateTime;
begin
DMin := DateOf(Min(DFrom,DTo));
DMax := DateOf(Max(DFrom,DTo));
DaysCount := trunc(DaySpan(DMin,DMax))+1;

if ExcludeWe then begin
Dec(DaysCount,trunc(WeekSpan(DMin,DMax)*2)+1);
end;
end;

// un exemple d'utilisation pour AllDaysBetweenP voici.
procedure TForm1.Button1Click(Sender: TObject);
var DCount : integer;
begin
AllDaysFromTo(DCount,DTPicker1.Date,DTPicker2.Date,True);
Button1.Caption := format('%d jours',[DCount]);
end;

// un exemple d'utilisation pour AllDaysBetween voici.
procedure TForm1.Button2Click(Sender: TObject);
begin
Button2.Caption := format('%d jours',[AllDaysBetween(DTPicker1.Date,DTPicker2.Date,True)]);
end;

{
Un type TDate ou TDateTime on peu indifferement utiliser.
La propriété .Date ou .DateTime d'un composant TDateTimePicker nous pouvons donc a ces fonctions passer.
}

Que la force soit avec vous, mon jeune ami.

Si te convient la reponse, sur "Reponse accéptée" cliquer tu dois.

{YODA-}

La theorie c'est quand on sait tout, mais que rien ne fonctionne.
La pratique c'est quand tout fonctionne, mais que personne ne sait pourquoi.
<hr>
3
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
16 janv. 2006 à 19:50
salut!


Pour format, vas voir mon tuto sur la fonction Format sur ce site dans les tutoriaux. ICI
En gros c'est une fonction qui permet de convertir une ou plusieurs valeur de type different vers une chaine de caracteres et qui permet de remplacer IntToStr, FloatToStr ect...

<hr size ="2" width= "100%">
IsWeekDay() est un fonction qui renvoie True si le jours de la date transmise correspond a Samedi ou Dimanche.

exemple :

if IsWeekDay(Date) then caption := 'C'est le weekend!' else caption := 'Au boulot fainenant!';

Date correspond a la fonction Date qui renvois la date systeme.

IsWeekDay utilise la fonction DayOfTheWeek qui respecte la norme ISO 8601 (si je me trompe pas de numero) ou lundi correspond au premier jours de la semaine, contrairement a la fonction DayOfWeek qui considere Dimanche comme le premier jours de la semaine.


AllDaysBetween() calcul le nombre de jours qui separe les dates DFrom et DTo et permet d'exclure les jours correspondant aux weekend.

Le parametre ExcludeWE est facultatif et par defaut a false. cela veux dire que si on omets de le definir la fonction renverras tout les jours weekend inclus.
ecriture : AllDaysBetween(Date1,Date2);

Si on le definit a True, la fonction renverras le nombres de jours en excluant les weekend.
ecriture : AllDaysBetween(Date1,Date2,true);


AllDaysBetweenProc() est identique a AllDaysBetween a la difference qu'on lui transmet la variable qui vas stocker le nombre de jours.
exemple :

var NDJ : integer;
begin
AllDaysBetweenProc(NDJ, Date1, Date2);
// ou
AllDaysBetweenProc(NDJ, Date1, Date2, true);
end;

comme pour AllDaysBetween(), le parametre ExcludeWE est facultatif.

cette fonction permet en fait une ecriture plus rapide que :

NDJ := AllDaysBetween(Date1,Date2);

quand on veux stocker le resultat dans une variable de type Integer.


voici un patch pour l'erreur de retour quand les date sont identitque :

function AllDaysBetween(const DFrom,DTo : TDateTime; const ExcludeWE : boolean = false) : integer;
var DMin,DMax : TDateTime;
WS : integer;
begin
if DFrom = DTo then begin
result := 1;
exit;
end;

DMin := DateOf(Min(DFrom,DTo));
DMax := DateOf(Max(DFrom,DTo));
Result := trunc(DaySpan(DMin,DMax))+1;

if ExcludeWe then begin
WS := trunc(WeekSpan(DMin,DMax)*2);
if result < 7 then Dec(WS,1);
if WS > 0 then result := result - (WS+1);
end;
end;

procedure AllDaysBetweenProc(out DaysCount : integer; const DFrom,DTo : TDateTime; const ExcludeWE : boolean = false);
var DMin,DMax : TDateTime;
WS : integer;
begin
if DFrom = DTo then begin
DaysCount := 1;
exit;
end;

DMin := DateOf(Min(DFrom,DTo));
DMax := DateOf(Max(DFrom,DTo));
DaysCount := trunc(DaySpan(DMin,DMax))+1;

if ExcludeWe then begin
WS := trunc(WeekSpan(DMin,DMax)*2);
if DaysCount < 7 then Dec(WS,1);
if WS > 0 then Dec(DaysCount,WS+1);
end;
end;


J'ais fait de nombreux test pour elaborer et debugger les fonctions que je te donne ici... les bugs sont donc maintenant exclus.

pose Deux TDateTimePicker sur ta fiche, et transmet les propriétés .Date a la fontion AllDaysBetween ou la procedure AllDaysBetweenProc.

exemple du programme :

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls;

type
TForm1 = class(TForm)
DateTimePicker1: TDateTimePicker;
DateTimePicker2: TDateTimePicker;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
procedure DateTimePicker1Change(Sender: TObject);
private
{ Déclarations privées }
public
{ Déclarations publiques }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}
uses DateUtils, Math;

function AllDaysBetween(const DFrom,DTo : TDateTime; const ExcludeWE : boolean = false) : integer;
var DMin,DMax : TDateTime; WS : integer;
begin
if DFrom = DTo then begin result := 1; exit; end;
DMin := DateOf(Min(DFrom,DTo)); DMax := DateOf(Max(DFrom,DTo));
Result := trunc(DaySpan(DMin,DMax))+1;
if ExcludeWe then begin
WS := trunc(WeekSpan(DMin,DMax)*2);
if result < 7 then Dec(WS,1);
if WS > 0 then result := result - (WS+1);
end;
end;

procedure AllDaysBetweenProc(out DaysCount : integer; const DFrom,DTo : TDateTime; const ExcludeWE : boolean = false);
var DMin,DMax : TDateTime; WS : integer;
begin
if DFrom = DTo then begin DaysCount := 1; exit; end;
DMin := DateOf(Min(DFrom,DTo)); DMax := DateOf(Max(DFrom,DTo));
DaysCount := trunc(DaySpan(DMin,DMax))+1;
if ExcludeWe then begin
WS := trunc(WeekSpan(DMin,DMax)*2);
if DaysCount < 7 then Dec(WS,1);
if WS > 0 then Dec(DaysCount,WS+1);
end;
end;

procedure TForm1.DateTimePickerChange(Sender: TObject);
var NDJ1,NDJ2 : integer;
begin
AllDaysBetweenProc(NDJ1,DateTimePicker1.Date,DateTimePicker2.Date);
AllDaysBetweenProc(NDJ2,DateTimePicker1.Date,DateTimePicker2.Date,true);
Label1.Caption := format('%d',[NDJ1]);
Label2.Caption := format('%d',[NDJ2]);

Label3.Caption := format('%d',[AllDaysBetween(DateTimePicker1.Date,DateTimePicker2.Date)]);
Label4.Caption := format('%d',[AllDaysBetween(DateTimePicker1.Date,DateTimePicker2.Date,true)]);
end;

end.

ne pas oublier de declarer dans la close USES les unités DateUtils et Math.

DateTimePickerChange() est a placer dans les evenement OnChange des deux TDateTimePicker.

<hr size ="2" width="100%">
voila, tout fonctionne correctement maintenant.

La theorie c'est quand on sait tout, mais que rien ne fonctionne.
La pratique c'est quand tout fonctionne, mais que personne ne sait pourquoi.
<hr>
3
guigui265 Messages postés 113 Date d'inscription mercredi 29 novembre 2000 Statut Membre Dernière intervention 16 avril 2006
16 janv. 2006 à 09:32
Merci de ton aide, mais il me reste quelques pb, au nivo du compteur.
il compte les week end mais pas le lundi et le vendredi, ce qui n'est pas le but de l'appli.
de plus,je ne compren pa commen sont utilisé lé fonction alldaybetween et isweekday, et je ne compren la la structure ...caption:=FORMAT?(...)
Merci
Guigs
0
Rejoignez-nous