Date à la limite de 30 jours. Pas normal... [Résolu]

Messages postés
190
Date d'inscription
mercredi 24 mai 2006
Statut
Membre
Dernière intervention
28 août 2015
- - Dernière réponse : Leader2000
Messages postés
190
Date d'inscription
mercredi 24 mai 2006
Statut
Membre
Dernière intervention
28 août 2015
- 15 févr. 2013 à 10:59
Salut!

Je suis derrière une solution qui me preoccupe, il y a quelques jours.
J'ai sur mon form deux tdateTime (EntradaAlojam et SaidaAlojam) sur lequels se font les calculs des jours et un tedit (numDias_alojam). Tous marchent bien!
Il n'arrive pas à calculer par exemple, 10-02-2013 au 10-03-2013. Je m'explique: si j'inserai 10-02-2013 au 09-03-2013 il affiche dans mon edit 29. Mais si je mets 10-02-2013 au 10-03-2013 il m'affiche 0. En un mot, le calcule ne se fait seulement qu'à la limite des 30 jours au maximum.
Pouvez-vous voir où ai-je failli?

Merci.

procedure Bonjour;
  public
    { Public declarations }
  end;

var
  AlojamentoFactu: TAlojamentoFactu;

implementation

uses LunaFactuReservas, LunaVistaGeral, LunaSenha1, LunaSenhaCaixaDiaro,
  LunaAlteracaoDadosFichaCliente, LunaSenhaAlteracaoFichaCliente;

{$R *.dfm}


{
Le retour du résultat est True si la différence est positive, False dans le cas
contraire.
Years, Months et Days sont toujours en valeur absolue.
}

function GetYMDBetween(FromDate, ToDate: TDateTime;
  var Years, Months, Days: Integer): Boolean;
var
  FromY, FromM, FromD,    // from date
  ToY, ToM, ToD: Word;    // to date
  TmpDate: TDateTime;
  PreviousMonth: Byte;
  DaysInMonth: Byte;
begin
  Result := FromDate <= ToDate;
  if not Result then
  begin
    TmpDate := ToDate;
    ToDate := FromDate;
    FromDate := TmpDate;
  end;
  DecodeDate(ToDate, ToY, ToM, ToD);
  DecodeDate(FromDate, FromY, FromM, FromD);
  Years := ToY - FromY;
  Months := ToM - FromM;
  Days := ToD - FromD;
  if Days < 0 then
  begin
    Dec(Months);
    PreviousMonth :ToM + (Byte(ToM 1) * 12) - 1;
    case PreviousMonth of
      1,3,5,7,8,10,12: DaysInMonth := 31;
      4,6,9,11       : DaysInMonth := 30;
      else
        DaysInMonth := 28 + Byte(IsLeapYear(ToY));
    end;
    Days := DaysInMonth - Abs(Days);
  end;
  if Months < 0 then
  begin
    Dec(Years);
    Months := 12 - Abs(Months);
  end;
end;

procedure TAlojamentoFactu.Bonjour;
const Positive: array[Boolean] of string = ('-', '');
var
  ToDate,               // date d'arrivée (en principe la plus récente)
  FromDate: TDateTime;  // date de départ (en principe la plus ancienne)
  Years, Months, Days: Integer;
  Difference: string;
  IsPositive: Boolean;  // IsPositive = ToDate > FromDate
begin
  { Affichage de la date dans les panels }
  //pnlTitleFrom.Caption := FormatDateTime('mmmm yyyy', CalendarFrom.Date);
  //pnlTitleTo.Caption := FormatDateTime('mmmm yyyy', CalendarTo.Date);

  { Recueil des dates dans les variable au format TDateTime }
  FromDate := EntradaAlojam.Date;
  ToDate := SaidaAlojam.Date;

  { Utilisation de la fonction GetYMDBetween() }
  IsPositive := GetYMDBetween(FromDate, ToDate, Years, Months, Days);

  { Mise en forme des données }
  Difference :=
  Format('%s %d', [Positive[IsPositive], Days]);
    //Format('%s %d an(s) %d moi(s) %d jour(s)', [Positive[IsPositive], Years, Months, Days]);

  { Affichage dans l'Edit }
  numDias_Alojam.Text := Difference;
  edt_numDias_reservas.Text:= Difference;
  //edt_numDias_reservas.Text := Difference;

end;
Afficher la suite 

12 réponses

Meilleure réponse
Messages postés
429
Date d'inscription
samedi 17 mai 2003
Statut
Membre
Dernière intervention
6 mai 2019
16
3
Merci
Utilise donc la fonction DayBetween qui se situe dans DateUtils, comme suggéré par beckerich.
Et laisse donc tomber le test de validité (if not result, que veux-tu tester avec ?) et toutes ces variables inutiles censées compter le nombre de mois ou d'années.
Concrètement, en utilisant le nom de tes composants, il suffit de faire :
uses DateUtils;
procedure TAlojamentoFactu.Bonjour;
var
  FromDate, ToDate: TDate;
  iDifference: Integer;
  sDifference: string;
begin
  FromDate := EntradaAlojam.Date;
  ToDate := SaidaAlojam.Date;
  iDifference := DaysBetween(ToDate, FromDate);
  sDifference := IntToStr(iDifference);
  numDias_Alojam.Text := sDifference;
  edt_numDias_reservas.Text:= sDifference;
end;


Rien de plus.

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 140 internautes nous ont dit merci ce mois-ci

Commenter la réponse de korgis
Messages postés
429
Date d'inscription
samedi 17 mai 2003
Statut
Membre
Dernière intervention
6 mai 2019
16
0
Merci
Salut,

Cette fonction n'est pas adaptée à ce que tu veux faire.
Pour retourner le nombre de jours compris entre 2 dates, ceci conviendra mieux :

function NumOfDays(FromDate, ToDate: TDate): Word;
begin
  Result := Trunc(ToDate) - Trunc(FromDate);
end;
Commenter la réponse de korgis
Messages postés
308
Date d'inscription
jeudi 29 septembre 2005
Statut
Membre
Dernière intervention
17 septembre 2013
1
0
Merci
Bonjour,

pourquoi vouloir réinventer la roue ?

uses
DateUtils;

function DaysBetween ( const ToDate, FromDate : TDateTime ) : Integer;

Luc.
Commenter la réponse de beckerich
Messages postés
429
Date d'inscription
samedi 17 mai 2003
Statut
Membre
Dernière intervention
6 mai 2019
16
0
Merci
Je ne sais pas où j'avais la tête...
Il vaut mieux bien sûr utiliser un integer comme valeur de retour, ça laisse plus de possibilités, y compris que les dates soient inversées, le résultat étant alors négatif.
function NumOfDays(FromDate, ToDate: TDate): Integer;
begin
  Result := Trunc(ToDate) - Trunc(FromDate);
end;
Commenter la réponse de korgis
Messages postés
429
Date d'inscription
samedi 17 mai 2003
Statut
Membre
Dernière intervention
6 mai 2019
16
0
Merci
Argghh...
J'ai posté avant le message de beckerich n'apparaisse.
Oui, c'est vrai, DateUtils, apparu à partir de Delphi 6.
Commenter la réponse de korgis
Messages postés
429
Date d'inscription
samedi 17 mai 2003
Statut
Membre
Dernière intervention
6 mai 2019
16
0
Merci
Je suis allé voir sous D7.
Ouaip, ils la font comme moi...
function NumOfDays(FromDate, ToDate: TDate): Integer;
begin
  Result := Trunc(ToDate) - Trunc(FromDate);
end;


copieurs...
Commenter la réponse de korgis
Messages postés
429
Date d'inscription
samedi 17 mai 2003
Statut
Membre
Dernière intervention
6 mai 2019
16
0
Merci
M... j'ai balancé mon code...

Je recommence : ils la font comme moi...

function DaysBetween(const ANow, AThen: TDateTime): Integer;
begin
  Result := Trunc(DaySpan(ANow, AThen));
end;


copieurs...
Commenter la réponse de korgis
Messages postés
429
Date d'inscription
samedi 17 mai 2003
Statut
Membre
Dernière intervention
6 mai 2019
16
0
Merci
En fait, ils font pas tout à fait pareil...
Bon, je retourne me coucher.
Commenter la réponse de korgis
Messages postés
4307
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
2 janvier 2019
25
0
Merci
Uses DateUtils;


CQFD.
________________________________________________________
Commenter la réponse de f0xi
Messages postés
190
Date d'inscription
mercredi 24 mai 2006
Statut
Membre
Dernière intervention
28 août 2015
0
Merci
tout a été fait. Mais en run-time le curseur se plante exactement à la fin de cette ligne de code ci et rien n'evolue:

if not Result then

uses
DateUtils;

function NumOfDays(FromDate, ToDate: TDate): Integer;
var Years, Months, Days: Integer): Boolean;
var
FromY, FromM, FromD, // from date
ToY, ToM, ToD: Word; // to date
TmpDate: TDateTime;
PreviousMonth: Byte;
DaysInMonth: Byte;
begin
Result := Trunc(ToDate) - Trunc(FromDate);
if not Result then
begin
TmpDate := ToDate;
ToDate := FromDate;
FromDate := TmpDate;
end;



Developper est une dimension pour moi.
Leader2000
Commenter la réponse de Leader2000
Messages postés
273
Date d'inscription
samedi 13 juin 2009
Statut
Membre
Dernière intervention
18 avril 2015
8
0
Merci
Bonsoir,
1 - ton "if result then ..." plante car result - le resultat de ta fonction - est un "integer" (la diff entre FromDate et Todate) alors que ton "if" attend un resultat boolean.
if (result=0) then ... correct
if not result then ... plante
2 - tDateTime est en fait "double" qui contient:
nb jours depuis 01/01/1890 dans sa partie entière
fraction de jours dans sa paries decimale (0.5=12h ... précis jusqu'au 100e de sec. d'ou le trunc() pour ignoer l'heure dans la soustraction des dates.
Tu veux la diff en jours entre 2 dates (+ ou -)
nbJours := trunc(dat1)-trunc(dat2)
ajouter des jours integer dat1 ( + ou -)
dat2 := dat1 + NbJours;
ajouter des semaines
dat2 := dat1 + ( NbSem *7 )
ajouter des mois
dat2 := IncMonth(Dat1, NbMonth);
Salut
solilog
Commenter la réponse de solilog
Messages postés
190
Date d'inscription
mercredi 24 mai 2006
Statut
Membre
Dernière intervention
28 août 2015
0
Merci
@Korgis

Merci, tes codes sont très simples et beaucoup plus pratique que jamais!

Developper est une dimension pour moi.
Leader2000
Commenter la réponse de Leader2000