我试图在delphi 5中生成给定范围内的随机Tdatetime值,假设我们有以下格式的两个日期
date1=01/01/2018 12:35:32
date2=05/01/2018 21:35:32
我希望在此范围之间生成exaclty“x”日期。作为一个例子,我想从范围date1-> date2生成7个日期
randomdate[0]:=01/01/2018 12:35:32
randomdate[1]:=01/01/2018 14:35:12
randomdate[2]:=01/01/2018 16:42:22
randomdate[3]:=02/01/2018 21:12:01
randomdate[4]:=03/01/2018 11:13:12
randomdate[5]:=04/01/2018 22:20:05
randomdate[6]:=05/01/2018 20:30:05
问题是,如果第二个随机日期富含date2,则所有其他日期必须与date2相同,但如果时间到达23:59:59,则下一个日期将超出范围
喜欢流动的场景
randomdate[0]:=01/01/2018 12:35:32
randomdate[1]:=05/01/2018 23:59:59
.................................
!从现在开始的所有日期都将是
06/01/2018 23:59:59
超出我的范围!!
任何帮助将是欣赏它
在Andreas Suggestion之后是最终代码,他在D5上工作,所以我想在所有其他版本的delphi上工作
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls;
type
TForm1 = class(TForm)
RichEdit1: TRichEdit;
Edit1: TEdit;
Edit2: TEdit;
Button1: TButton;
Edit3: TEdit;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
function SecondsBetween(const Time1, Time2: TDateTime): Longint;
const SecsPerMin=60;
const MinsPerHour=60;
const HoursPerDay=24;
begin
result := Round(SecsPerMin * MinsPerHour * HoursPerDay * Abs(Time2 - Time1));
end;
function RandomDateTime( AFrom, ATo: TDateTime): TDateTime;
var
SecsBetween: int64;
begin
SecsBetween := SecondsBetween(AFrom,ATo);
result := AFrom + (Round(SecsBetween * Random) / (60*60*24));
end;
function CreateSortedListOfRandomDatetimes( AFrom, ATo: TDateTime; N: integer): TStringlist;
var
i: Integer;
begin
result := Tstringlist.Create;
try
// result.Capacity := N; // for an unnoticeable increase in performance
for i := 1 to N do result.Add(formatdatetime('dd/mm/yyyy hh:nn:ss',RandomDateTime(AFrom, ATo)));
result.Sort;
except
result.Free;
raise;
end;
end;
//edit1 Holds the 1st date which is 04/09/2018 16:00:00
//edit2 hold the 2nd date
//edit3 holds the N count value
procedure TForm1.Button1Click(Sender: TObject);
var
timestamps: Tstringlist;
i: Integer;
d1:Tdatetime;
d2:Tdatetime;
begin
d1:=StrtoDatetime(edit1.text);
d2:=StrtoDatetime(edit2.text);
timestamps := CreateSortedListOfRandomDatetimes(d1,d2 ,strtoInt(edit3.text));
try
RichEdit1.Lines.BeginUpdate;
try
RichEdit1.Lines.Clear;
for i := 0 to timestamps.Count - 1 do
RichEdit1.Lines.Add(timestamps.strings[i])
finally
RichEdit1.Lines.EndUpdate;
end;
finally
timestamps.Free;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
randomize;
end;
end.
在两个固定值之间生成随机TDateTime
值的函数可以这样写(uses DateUtils
):
function RandomDateTime(const AFrom, ATo: TDateTime): TDateTime;
var
SecsBetween: Int64;
begin
SecsBetween := SecondsBetween(AFrom, ATo);
result := IncSecond(AFrom, Round(SecsBetween * Random));
end;
要创建这些的排序列表,请使用您喜欢的排序方法。在现代Delphi中,您可以使用内置的通用列表:
function CreateSortedListOfRandomDatetimes(const AFrom, ATo: TDateTime; N: integer): TList<TDateTime>;
var
i: Integer;
begin
result := TList<TDateTime>.Create;
try
result.Capacity := N; // for an unnoticeable increase in performance
for i := 1 to N do
result.Add(RandomDateTime(AFrom, ATo));
result.Sort;
except
result.Free;
raise;
end;
end;
试试看:
procedure TForm1.FormCreate(Sender: TObject);
var
timestamps: TList<TDateTime>;
i: Integer;
begin
timestamps := CreateSortedListOfRandomDatetimes(
EncodeDateTime(2000, 1, 1, 0, 0, 0, 0),
EncodeDateTime(2000, 12, 31, 23, 59, 59, 999),
10
);
try
RichEdit1.Lines.BeginUpdate;
try
RichEdit1.Lines.Clear;
for i := 0 to timestamps.Count - 1 do
RichEdit1.Lines.Add(DateTimeToStr(timestamps[i]))
finally
RichEdit1.Lines.EndUpdate;
end;
finally
timestamps.Free;
end;
end;
(这种方法可能会产生重复的日期时间.Q没有明确提到是否允许这样。而且,它只能以第二精度工作,而不是毫秒精度。你可能想要改变它,或者至少从AFrom
中删除毫秒。)