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

Leader2000 190 Messages postés mercredi 24 mai 2006Date d'inscription 28 août 2015 Dernière intervention - 9 févr. 2013 à 11:37 - Dernière réponse : Leader2000 190 Messages postés mercredi 24 mai 2006Date d'inscription 28 août 2015 Dernière intervention
- 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 

Votre réponse

12 réponses

korgis 415 Messages postés samedi 17 mai 2003Date d'inscription 11 mai 2018 Dernière intervention - 12 févr. 2013 à 15:53
+3
Utile
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.
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de korgis
korgis 415 Messages postés samedi 17 mai 2003Date d'inscription 11 mai 2018 Dernière intervention - 10 févr. 2013 à 08:39
0
Utile
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
beckerich 309 Messages postés jeudi 29 septembre 2005Date d'inscription 17 septembre 2013 Dernière intervention - 10 févr. 2013 à 17:24
0
Utile
Bonjour,

pourquoi vouloir réinventer la roue ?

uses
DateUtils;

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

Luc.
Commenter la réponse de beckerich
korgis 415 Messages postés samedi 17 mai 2003Date d'inscription 11 mai 2018 Dernière intervention - 10 févr. 2013 à 17:27
0
Utile
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
korgis 415 Messages postés samedi 17 mai 2003Date d'inscription 11 mai 2018 Dernière intervention - 10 févr. 2013 à 17:30
0
Utile
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
korgis 415 Messages postés samedi 17 mai 2003Date d'inscription 11 mai 2018 Dernière intervention - 10 févr. 2013 à 17:35
0
Utile
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
korgis 415 Messages postés samedi 17 mai 2003Date d'inscription 11 mai 2018 Dernière intervention - 10 févr. 2013 à 17:37
0
Utile
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
korgis 415 Messages postés samedi 17 mai 2003Date d'inscription 11 mai 2018 Dernière intervention - 10 févr. 2013 à 17:39
0
Utile
En fait, ils font pas tout à fait pareil...
Bon, je retourne me coucher.
Commenter la réponse de korgis
f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscription 9 mars 2018 Dernière intervention - 11 févr. 2013 à 10:38
0
Utile
Uses DateUtils;


CQFD.
________________________________________________________
Commenter la réponse de f0xi
Leader2000 190 Messages postés mercredi 24 mai 2006Date d'inscription 28 août 2015 Dernière intervention - 12 févr. 2013 à 12:02
0
Utile
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
solilog 273 Messages postés samedi 13 juin 2009Date d'inscription 18 avril 2015 Dernière intervention - 12 févr. 2013 à 19:50
0
Utile
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
Leader2000 190 Messages postés mercredi 24 mai 2006Date d'inscription 28 août 2015 Dernière intervention - 15 févr. 2013 à 10:59
0
Utile
@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

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.