Советы по Delphi. Версия 1.4.3 от 1.1.2001 - страница 5
>{*******************************************************************
>ФАЙЛ : TIMEEX.PAS
>ПРИМЕЧАНИЕ : Создайте форму, содержащую 1 TTimer и 6 TLabel. Установите событие OnTimer у TTimer на TForm.Timer1.Timer
>********************************************************************}
>unit Time;
>interface
>uses
> SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,Forms, Dialogs, ExtCtrls, StdCtrls;
>type
> TForm1 = class(TForm)
> Timer1: TTimer;
> Label1: TLabel; {Caption : 'Старт :'}
> Label2: TLabel;
> Label3: TLabel; {Caption : 'Время : '}
> Label4: TLabel;
> Label5: TLabel; {Caption : 'Истекшее время:'}
> Label6: TLabel;
> procedure FormCreate(Sender: TObject);
> procedure Timer1Timer(Sender: TObject);
> private { Private declarations }
> TimeStart : TDateTime;
> public { Public declarations }
> end;
>var
> Form1: TForm1;
>implementation
> {$R *.DFM}
>procedure TForm1.FormCreate(Sender: TObject);
>begin
> TimeStart := Now;
> Label2.Caption := TimeToStr(Now);
>end;
>procedure TForm1.Timer1Timer(Sender: TObject);
>var
> tt : TDateTime;
>begin
> Label4.Caption := TimeToStr(Now);
> tt:= Now - TimeStart;
> Label6.Caption:= TimeToStr(tt);
>end;
>end.
Проблема со временем
Delphi 1
…я нашел Time24Hour в файлах помощи, как вы и советовали. Но…
вот код для EncodeTime в SysUtils.Pas file:
>function DoEncodeTime(Hour, Min, Sec, MSec: Word; var Time: TDateTime): Boolean;
>begin
> Result := False;
> if (Hour < 24) and (Min < 60) and (Sec < 60) and (MSec < 1000) then begin
>Time := (LongMul(Hour * 60 + Min, 60000) + Sec * 1000 + MSec) / MSecsPerDay;
> Result := True;
> end;
>end;
>function EncodeTime(Hour, Min, Sec, MSec: Word): TDateTime;
>begin
> if not DoEncodeTime(Hour, Min, Sec, MSec, Result) then ConvertError(LoadStr(STimeEncodeError));
>end;
Как вы можете видеть, проверка Time24Hour присутствует. Я думал в Browser все будет также. Ничего подобного! Я уж грешным делом подумал, что Time24Hour объявили устаревшим, исключили из поддержки, выбросили частично из кода, но забыли почистить файл помощи. Вы так не думаете?
Переменная времени
Delphi 1
Используйте переменную типа TDateTime.
>procedure TForm1.XXXXXXXClick(Sender: TObject);
>var StartTime, EndTime, ElapsedTime :TDateTime;
>begin
> StartTime := Now;
> {Здесь поместите свой код}
> EndTime := Now;
> ElapsedTime := EndTime - StartTime;
> Label1.Caption := TimeToStr(ElapsedTime);
>end;
>{теперь все это в памяти, но в нашем случае это хорошее место. }
>var
> before,after,elapsed : TDateTime;
> Ehour, Emin, Esec, Emsec : WORD;
>…
> before := now;
> some_process();
> after := now;
> elapsed := after - before;
> decodetime(elapsed, Ehour, Emin, Esec, Emsec);
теперь Ehour:Emin:Esec.Emsec будет содержать истекшее время.
Это то, что я хотел. fStartWhen содержит дату/время начала процесса. (fStartWhen := NOW). OneSecond — константа, определенная как 1/24/3600. (Да, эта программа может выполняться для нескольких дней. Но даже самый быстрый P5 может не справиться с большим количеством данных!)
>PROCEDURE TformDBLoad.UpdateTime;
>VAR Delta: TDateTime
>BEGIN
> fLastUpdate := NOW
> IF ABS(fStartWhen - fLastUpdate ) < OneSecond THEN EXIT
>Delta := fLastUpdate - fStartWhendoElapsedTime.Caption := FORMAT('%1. дней из %s', [INT(Delta),FORMATDATETIME('hh:nn:ss', FRAC(Delta))])
>END;
Математика
Как научить Delphi делать правильное округление дробных чисел?
Nomadic советует:
Целая коллекция способов -
Для решения этой проблемы мною написана функция, которую можно модифицировать для всех случаев. Смысл заключается в том, что рассматривается строка. После этого все проблемы с округлением снялись.
>Function RoundStr(Zn:Real;kol_zn:Integer):Real;
>{Zn-значение; Kol_Zn-Кол-во знаков после запятой}
>Var
> snl,s,s0,s1,s2:String;
> n,n1:Real;
> nn,i:Integer;
>begin
> s:=FloatToStr(Zn);
> if (Pos(',',s)>0) and (Zn>0) and (Length(Copy(s,Pos(',',s)+1,length(s)))>kol_zn) then begin
>s0 := Copy(s,1,Pos(',',s)+kol_zn-1);
> s1 := Copy(s,1,Pos(',',s)+kol_zn+2);
> s2 := Copy(s1,Pos(',',s1)+kol_zn,Length(s1));
> n := StrToInt(s2)/100;nn := Round(n);
> if nn >= 10 then begin
>snl := '0,';
> For i := 1 to kol_zn - 1 do snl := snl + '0';
> snl := snl+'1';
> n1 := StrToFloat(Copy(s,1,Pos(',',s)+kol_zn))+StrToFloat(snl);