2012-08-27 18 views
5

私は何千ものファイルをダウンロードする長いループをしています。私は数時間かかる可能性があるので、残りの推定時間を表示したいと思います。しかし、私が書いたことで、私はミリ秒の平均値を得ます。平均ダウンロード時間をミリ秒からTDateTimeに変更するにはどうすればよいですか?私はLabel1.Captionを設定するよどこミリ秒をTDateTimeに変換するにはどうすればよいですか?

参照してください:

procedure DoWork; 
const 
    AVG_BASE = 20; //recent files to record for average, could be tweaked 
var 
    Avg: TStringList; //for calculating average 
    X, Y: Integer; //loop iterators 
    TS, TE: DWORD; //tick counts 
    A: Integer; //for calculating average 
begin 
    Avg:= TStringList.Create; 
    try 
    for X:= 0 to FilesToDownload.Count - 1 do begin //iterate through downloads 
     if FStopDownload then Break; //for cancelling 
     if Avg.Count >= AVG_BASE then //if list count is 20 
     Avg.Delete(0); //remove the oldest average 
     TS:= GetTickCount; //get time started 
     try 
     DownloadTheFile(X); //actual file download process 
     finally 
     TE:= GetTickCount - TS; //get time elapsed 
     end; 
     Avg.Add(IntToStr(TE)); //add download time to average list 
     A:= 0; //reset average to 0 
     for Y:= 0 to Avg.Count - 1 do //iterate through average list 
     A:= A + StrToIntDef(Avg[Y], 0); //add to total download time 
     A:= A div Avg.Count; //divide count to get average download time 
     Label1.Caption:= IntToStr(A); //<-- How to convert to TDateTime? 
    end; 
    finally 
    Avg.Free; 
    end; 
end; 

PSを - 私は私の文字列と確信しているので、私は、最後の20(またはAVG_BASE)のダウンロードの平均速度を計算する様々な方法に開いていますリストソリューションは最高ではありません。私はすべてのダウンロードに基づいてそれを計算したくないのですが、速度はその時間に変わるかもしれません。したがって、私はちょうどあなたが、あなたがconstructorに経過ティックを渡して新しいインスタンスを作成することができ、ここからあなたは日、時間を使うことができ、TTimeSpanレコードを使用することができる代わりのTDateTimeの最後の20

答えて

10

TDateTimeの値は基本的にdoubleです。ここで、整数部分は日数であり、小数は時間です。

日で24 * 60 * 60 = 86400秒(SecsPerDay定数がsysutilsの中で宣言)があるので、TDateTimeのように行う取得する:クロックへ

dt := A/(SecsPerDay*1000.0); // A is the number of milliseconds 

良い方法時間は、使用することですユニットTStopWatchの構成Diagnostics

例:TStopWatchため

Type 
    TMovingAverage = record 
    private 
    FData: array of integer; 
    FSum: integer; 
    FCurrentAverage: integer; 
    FAddIx: integer; 
    FAddedValues: integer; 
    public 
    constructor Create(length: integer); 
    procedure Add(newValue: integer); 
    function Average : Integer; 
    end; 

procedure TMovingAverage.Add(newValue: integer); 
var i : integer; 
begin 
    FSum := FSum + newValue - FData[FAddIx]; 
    FData[FAddIx] := newValue; 
    FAddIx := (FAddIx + 1) mod Length(FData); 
    if (FAddedValues < Length(FData)) then 
    Inc(FAddedValues); 
    FCurrentAverage := FSum div FAddedValues; 
end; 

function TMovingAverage.Average: Integer; 
begin 
    Result := FCurrentAverage; 
end; 

constructor TMovingAverage.Create(length: integer); 
var 
    i : integer; 
begin 
    SetLength(FData,length); 
    for i := 0 to length - 1 do 
    FData[i] := 0; 
    FSum := 0; 
    FCurrentAverage := 0; 
    FAddIx := 0; 
    FAddedValues := 0; 
end; 
+1

1:

sw.Create; .. sw.Start; // Do something sw.Stop; A := sw.ElapsedMilliSeconds; // or as RRUZ suggested ts := sw.Elapsed; to get the TimeSpan 

このmoving averageレコードを使用することを検討して、あなたの平均時間を得るために。一部のコンピュータでは、TStopWatchの基礎となるWin32 API関数が安定せず、正しく動作しないことが判明しました(Windows XP、ICH4/ICH5時代のチップセットを搭載した特定のIntel Pentium 4チップセット)。現代のハードウェア(Core2Duo以降)ではもう問題ではありませんが、...(正確にやろうとする)ミリ秒単位で時間を費やしています.Windows APIは、試してみると大きな悲しみを与えてくれました。 TStopWatchはGetTickCountよりもはるかに正確です!私は、 –

+0

+1確かに、もし私もファイルサイズを考慮に入れることができれば.......遠く異なる話........ –

8

をチェックしています分、秒、およびミリ秒のプロパティを使用して経過時間を表示します。今度は残りの時間を計算するために、ダウンロードする総バイト数と現在ダウンロードされているバイト数が必要です。

関連する問題