[unite] randdate : fonction randrangedate et randomdate, generatrices de dates aleatoires


Description

Bonjour a tous!

voici deux fonctions qui vous seront peut etre utile et surtout qui vont vous apprendre a generer des dates aleatoirement.

RandomDate(const LockToNow : boolean = false), genere une date aleatoire soit :
LockToNow a false (par defaut) : du 01/01/0001 au 31/12/9999
LockToNow a true : du 01/01/0001 au jours d'aujourd'hui (fonction date)

RandRangeDate(const MinDate,MaxDate : TDateTime), genere une date aleatoire dans l'interval MinDate..MaxDate inclus.

la source dans le Zip est commentée.

Source / Exemple :


{
 RANDDATE v0.3
}
unit RandDate;

interface
uses math, dateutils, sysutils;

function RandomDate(const LockToNow : boolean = false) : TDateTime;
function RandRangeDate(const MinDate,MaxDate : TDateTime) : TDateTime;

implementation

function _Clamp(const aValue,aMin,aMax : integer) : integer;
begin
  result := Max(Min(aValue,aMax),aMin);
end;

function RandRangeDate(const MinDate,MaxDate : TDateTime) : TDateTime;
var aD,
    MinD,MaxD,D,
    MinM,MaxM,M,
    MinY,MaxY,Y : word;
begin
  DecodeDate(MinDate,MinY,MinM,MinD);
  DecodeDate(MaxDate,MaxY,MaxM,MaxD);
  Y := _Clamp(RandomRange(MinY,MaxY+1),MinY,MaxY);
  if Y = MinY then
     M := _Clamp(RandomRange(MinM,12+1),MinM,12)
  else
  if Y = MaxY then
     M := _Clamp(RandomRange(1,MaxM+1),1,MaxM)
  else
     M := _Clamp(RandomRange(1,12+1),1,12);
  case M of
     2               : if IsLeapYear(Y) then aD := 29 else aD := 28;
     4,6,9,11        : aD := 30;
     1,3,5,7,8,10,12 : aD := 31;
  end;
  if M = MinM then
     D := _Clamp(RandomRange(MinD,aD+1),MinD,aD)
  else
  if M = MaxM then
     D := _Clamp(RandomRange(1,MaxD+1),1,MaxD)
  else
     D := _Clamp(RandomRange(1,aD+1),1,aD);
  result := EncodeDate(Y,M,D);
end;

function RandomDate(const LockToNow : boolean = false) : TDateTime;
var aD,
    MaxD,D,
    MaxM,M,
    MaxY,Y : word;
begin
  if not LockToNow then begin
     MaxD := 31;
     MaxM := 12;
     MaxY := 9999;
  end else begin
     DecodeDate(Date,MaxY,MaxM,MaxD);
  end;
  Y := _Clamp(RandomRange(1,MaxY+1),1,MaxY);
  if Y = MaxY then
     M := _Clamp(RandomRange(1,MaxM+1),1,MaxM)
  else
     M := _Clamp(RandomRange(1,12+1),1,12);
  case M of
     2               : if IsLeapYear(Y) then aD := 29 else aD := 28;
     4,6,9,11        : aD := 30;
     1,3,5,7,8,10,12 : aD := 31;
  end;
  if M = MaxM then
     D := _Clamp(RandomRange(1,MaxD+1),1,MaxD)
  else
     D := _Clamp(RandomRange(1,aD+1),1,aD);
  result := EncodeDate(Y,M,D);
end;

initialization
  randomize;
end.

Conclusion :


Grace a "_Clamp" (fonction interne de l'unité RandDate) le bug de randomrange (qu'il soit reparé ou non) ne pose aucun probleme.
_Clamp correpond a la fonction Clamp du C++ et a Max(Min(V,VMax),VMin) en delphi.

en cas d'erreur (ce qui ne devrait pas etre le cas grace au Clamping massif) EncodeDate declencheras une exception.

Codes Sources

A voir également

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.