Delphi生成日期时间范围之间的随机日期时间值  
官方Delphi 学习QQ群: 682628230(三千人)\n
频道

Delphi生成日期时间范围之间的随机日期时间值


Delphi生成日期时间范围之间的随机日期时间值

我正在尝试在 delphi中的给定范围内生成随机的Tdatetime值 让我们说两个日期都遵循以下格式
date1=01/01/2018 12:35:32 
date2=05/01/2018 21:35:32 

我要生成一个在此范围之间增加的“ 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建议之后,这里是在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.
1 个答案:
答案 0 :(得分:5)
可以像这样(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的毫秒数。)



推荐分享
图文皆来源于网络,内容仅做公益性分享,版权归原作者所有,如有侵权请告知删除!
 

Copyright © 2014 DelphiW.com 开发 源码 文档 技巧 All Rights Reserved
晋ICP备14006235号-8 晋公网安备 14108102000087号

执行时间: 0.047559976577759 seconds