我想获得当前时间,但是需要精确到毫秒以下,如:2003年1月5日16点38分20秒368毫秒... 我想获得当前时间,但是需要精确到毫秒以下,如:2003年1月5日16点38分20秒368毫秒...,即获得毫秒以下的时间,该怎么办????? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 edit1.text :=formatdatetime('yyyy年mm月dd日hh点mm分ss秒zzz毫秒',now); //获得系统"时:分:秒.毫秒"var Hour, Minute, Second, MSec: word; TimeStr: string;begin DecodeTime(Time, Hour, Minute, Second, MSec); TimeStr:= IntToStr(Hour)+':'+IntToStr(Minute)+':'+IntToStr(Second)+'.'+IntToStr(MSec); ShowMessage(TimeStr);end; queryperformancefrequency(frequency); queryperformancecounter(Tagscounter); nowcounter:=Tagscounter; while (nowcounter-tagscounter) < {定义时间间隔} do begin Application.ProcessMessages; queryperformancecounter(nowcounter); end; formatdatetime('yyyy-mm-dd-mm-ss-zzz',now) 两种利用windows api函数实现精确记时的方法。第一中方法是利用高性能频率记数(作者本人的称呼)法。利用这种方法要使用两个api函数queryperformancefrequency和queryperformancecounter。queryperformancefrequency函数获得高性能频率记数器的震荡频率。调用该函数后,函数会将系统频率记数器的震荡频率(每毫秒)保存到一个largeinteger中。不过利用该函数在几台机器上做过试验,结果都是1193180。读者朋友可以在自己的机器上试一下queryperformancecounter函数获得系统频率记数器的震荡次数,结果也保存到一个largenteger中。 很显然,如果在计时中首先使用queryperformancefrequency获得高性能频率记数器每毫秒的震荡次数,然后在计时开始时使用queryperformancecounter函数获得当前系统频率记数器的震荡次数。在计时结束时再调用queryperformancecounter函数获得系统频率记数器的震荡次数。将两者相减,再将结果除以频率记数器每毫秒的震荡次数,就可以获得某一事件经过的准确时间。(次数除以频率等于时间)另外的一种精确记时器的功能是利用多媒体记时器函数(这也是作者的定义,因为这个系列的函数是在winmm.dll中定义并且是为媒体播放服务的)。实现多媒体记时器首先要使用timesetevent函数建立计时事件。该函数在delphi中的mmsystem.pas中有定义,定义如下:function timesetevent(udelay, uresolution: uint; lpfunction: tfntimecallback; dwuser: dword; uflags: uint): mmresult; stdcall函数定义中参数udelay定义延迟时间,以毫秒为单位,该参数相当于timer控件的interval属性。参数uresolution定义记时精度,如果要求尽可能高的精度,要将该参数设置为0;参数lpfunction定义了timesetevent函数的回调函数。该函数相当于一个定时中断处理函数,每当经过一个udelay长度的时间间隔,该函数就会被调用,编程者可以在该函数中加入相应的处理语句。参数dwuser定义用户自定义的回调值,该值将传递给回调函数。参数uflags定义定时类型,如果要不间断的记时,该值应设置为1。如果函数调用成功,在系统中建立了一个多媒体记时器对象,每当经过一个udelay时间后lpfunction指定的函数都会被调用。同时函数返回一个对象标识,如果不再需要记时器则必须要使用timekillevent函数删除记时器对象。由于windows是一个多任务的操作系统,因此基于api调用的记时器的精度都会受到其它很多因素的干扰。到底这两中记时器的精度如何,我们来使用以下的程序进行验证:设置三种记时器(timer控件、高性能频率记数、多媒体记时器)。将它们的定时间隔设置为10毫秒,让它们不停工作直到达到一个比较长的时间(比如60秒),这样记时器的误差会被累计下来,然后同实际经过的时间相比较,就可以得到它们的精度。下面是具体的检测程序。unit unit1;interfaceuses windows, messages, sysutils, classes, graphics, controls, forms, dialogs,stdctrls, extctrls,mmsystem;type tform1 = class(tform) edit1: tedit; edit2: tedit; edit3: tedit; button1: tbutton; button2: tbutton; timer1: ttimer; procedure formcreate(sender: tobject); procedure button1click(sender: tobject); procedure timer1timer(sender: tobject); procedure button2click(sender: tobject); private { private declarations } public { public declarations } end;var form1: tform1; acttime1,acttime2:cardinal; smmcount,stimercount,spcount:single; htimeid:integer; iten:integer; protimecallback:tfntimecallback;procedure timeproc(utimerid, umessage: uint; dwuser, dw1, dw2: dword) stdcall;procedure proendcount;implementation{$r *.dfm}//timesetevent的回调函数procedure proendcount;begin acttime2:=gettickcount-acttime1; form1.button2.enabled :=false; form1.button1.enabled :=true; form1.timer1.enabled :=false; smmcount:=60; stimercount:=60; spcount:=-1; timekillevent(htimeid);end;procedure timeproc(utimerid, umessage: uint;dwuser, dw1, dw2: dword) stdcall;begin form1.edit2.text:=floattostr(smmcount); smmcount:=smmcount-0.01;end;procedure tform1.formcreate(sender: tobject);begin button1.caption :='开始倒计时'; button2.caption :='结束倒计时'; button2.enabled :=false; button1.enabled :=true; timer1.enabled :=false; smmcount:=60; stimercount:=60; spcount:=60;end;procedure tform1.button1click(sender: tobject);var lgtick1,lgtick2,lgper:tlargeinteger; ftemp:single;begin button2.enabled :=true; button1.enabled :=false; timer1.enabled :=true; timer1.interval :=10; protimecallback:=timeproc; htimeid:=timesetevent(10,0,protimecallback,1,1); acttime1:=gettickcount; //获得系统的高性能频率计数器在一毫秒内的震动次数 queryperformancefrequency(lgper); ftemp:=lgper/1000; iten:=trunc(ftemp*10); queryperformancecounter(lgtick1); lgtick2:=lgtick1; spcount:=60; while spcount>0 do begin queryperformancecounter(lgtick2); //如果时钟震动次数超过10毫秒的次数则刷新edit3的显示 if lgtick2 - lgtick1 > iten then begin lgtick1 := lgtick2; spcount := spcount - 0.01; edit3.text := floattostr(spcount); application.processmessages; end; end;end;procedure tform1.timer1timer(sender: tobject);begin edit1.text := floattostr(stimercount); stimercount:=stimercount-0.01;end;procedure tform1.button2click(sender: tobject);begin proendcount; //显示从开始记数到记数实际经过的时间 showmessage('实际经过时间'+inttostr(acttime2)+'毫秒');end;end. 运行程序,点击“开始倒记时”按钮,程序开始60秒倒记时,由于上面的程序只涉及了记时器程序的原理而没有将错误处理加入其中,所以不要等60秒倒记时结束。点击“结束倒记时”按钮可以结束倒记时。这时在弹出对话框中会显示实际经过的时间(单位为毫秒),将三个文本框内的时间乘以1000再加上实际经过的时间,越接近60000,则记时精度越高。下面是在我的机器上的执行结果。 从上面的结果看,由delphi的timer控件建立的记时器的精度十分差,无法在实际中使用,而利用高性能频率记数法和多媒体计数器法的误差都在1%以下。考虑到程序中在文本框中显示时间对程序所造成的影响,这个误差在应用中是完全可以忽略的。另外在运行程序时作者还发现一个问题,如果在倒记时时拖动窗口,文本框中的显示都会停止,而当停止窗口拖放后,多媒体记时器显示会跳过这段时间记时,而其它两种记时器显示倒记时却还是从原来的时间倒数。这说明多媒体记时器是在独立的线程中运行的,不会受到程序的影响。综合上面的介绍和范例,我们可以看到,如果要建立高精度的记时器,使用多媒体记时器是比较好的选择。而高性能频率记数法比较适合计算某个耗时十分短的过程所消耗的时间(例如分析程序中某个被多次调用的程序段执行时间以优化程序),因为毕竟高性能频率记数的理论可以达到微秒级别。timer控件虽然精度比上面两者差很多,但是它使用方便,在要求不高的场合它还是最佳选择 http://expert.csdn.net/Expert/topic/1943/1943718.xml?temp=.6206781 Tbookmarklist的问题 急求!! cxGrid中设置了GridMode=True,怎样再可以使用多选,遍历全部或者部分超出表格显示范围的数据???分数不够可另外加贴送分!! 哈哈哈 又一个access查询问题,解决马上给分! 如何对“计划任务”编程? 请问如何得到...? 请教一下消息传递机制的问题! 如何调用C++Builder写的DLL 请教:如何才能在QUICKREPORT中用CANVAS直接画图? “关于:怎样才能让“RichEdit”控件正确删除中文字?”的补充 介绍一本深入学习VCL的书籍 如何关闭显示器?用什么API函数。
Hour, Minute, Second, MSec: word;
TimeStr: string;
begin
DecodeTime(Time, Hour, Minute, Second, MSec);
TimeStr:= IntToStr(Hour)+':'+IntToStr(Minute)+':'+IntToStr(Second)+'.'+IntToStr(MSec);
ShowMessage(TimeStr);
end;
queryperformancecounter(Tagscounter);
nowcounter:=Tagscounter;
while (nowcounter-tagscounter) < {定义时间间隔} do
begin
Application.ProcessMessages;
queryperformancecounter(nowcounter);
end;
下面是具体的检测程序。unit unit1;interfaceuses
windows, messages, sysutils, classes, graphics, controls, forms, dialogs,stdctrls, extctrls,mmsystem;type
tform1 = class(tform)
edit1: tedit;
edit2: tedit;
edit3: tedit;
button1: tbutton;
button2: tbutton;
timer1: ttimer;
procedure formcreate(sender: tobject);
procedure button1click(sender: tobject);
procedure timer1timer(sender: tobject);
procedure button2click(sender: tobject);
private
{ private declarations }
public
{ public declarations }
end;var
form1: tform1;
acttime1,acttime2:cardinal;
smmcount,stimercount,spcount:single;
htimeid:integer;
iten:integer;
protimecallback:tfntimecallback;procedure timeproc(utimerid, umessage: uint; dwuser, dw1, dw2: dword) stdcall;procedure proendcount;implementation{$r *.dfm}//timesetevent的回调函数procedure proendcount;
begin
acttime2:=gettickcount-acttime1;
form1.button2.enabled :=false;
form1.button1.enabled :=true;
form1.timer1.enabled :=false;
smmcount:=60;
stimercount:=60;
spcount:=-1;
timekillevent(htimeid);
end;procedure timeproc(utimerid, umessage: uint;dwuser, dw1, dw2: dword) stdcall;
begin
form1.edit2.text:=floattostr(smmcount);
smmcount:=smmcount-0.01;
end;procedure tform1.formcreate(sender: tobject);
begin
button1.caption :='开始倒计时';
button2.caption :='结束倒计时';
button2.enabled :=false;
button1.enabled :=true;
timer1.enabled :=false;
smmcount:=60;
stimercount:=60;
spcount:=60;
end;procedure tform1.button1click(sender: tobject);
var
lgtick1,lgtick2,lgper:tlargeinteger;
ftemp:single;
begin
button2.enabled :=true;
button1.enabled :=false;
timer1.enabled :=true;
timer1.interval :=10;
protimecallback:=timeproc;
htimeid:=timesetevent(10,0,protimecallback,1,1);
acttime1:=gettickcount;
//获得系统的高性能频率计数器在一毫秒内的震动次数
queryperformancefrequency(lgper);
ftemp:=lgper/1000;
iten:=trunc(ftemp*10);
queryperformancecounter(lgtick1);
lgtick2:=lgtick1;
spcount:=60;
while spcount>0 do begin
queryperformancecounter(lgtick2);
//如果时钟震动次数超过10毫秒的次数则刷新edit3的显示
if lgtick2 - lgtick1 > iten then begin
lgtick1 := lgtick2;
spcount := spcount - 0.01;
edit3.text := floattostr(spcount);
application.processmessages;
end;
end;
end;procedure tform1.timer1timer(sender: tobject);begin
edit1.text := floattostr(stimercount);
stimercount:=stimercount-0.01;
end;procedure tform1.button2click(sender: tobject);begin
proendcount;
//显示从开始记数到记数实际经过的时间
showmessage('实际经过时间'+inttostr(acttime2)+'毫秒');
end;end. 运行程序,点击“开始倒记时”按钮,程序开始60秒倒记时,由于上面的程序只涉及了记时器程序的原理而没有将错误处理加入其中,所以不要等60秒倒记时结束。点击“结束倒记时”按钮可以结束倒记时。这时在弹出对话框中会显示实际经过的时间(单位为毫秒),将三个文本框内的时间乘以1000再加上实际经过的时间,越接近60000,则记时精度越高。下面是在我的机器上的执行结果。
从上面的结果看,由delphi的timer控件建立的记时器的精度十分差,无法在实际中使用,而利用高性能频率记数法和多媒体计数器法的误差都在1%以下。考虑到程序中在文本框中显示时间对程序所造成的影响,这个误差在应用中是完全可以忽略的。
另外在运行程序时作者还发现一个问题,如果在倒记时时拖动窗口,文本框中的显示都会停止,而当停止窗口拖放后,多媒体记时器显示会跳过这段时间记时,而其它两种记时器显示倒记时却还是从原来的时间倒数。这说明多媒体记时器是在独立的线程中运行的,不会受到程序的影响。综合上面的介绍和范例,我们可以看到,如果要建立高精度的记时器,使用多媒体记时器是比较好的选择。而高性能频率记数法比较适合计算某个耗时十分短的过程所消耗的时间(例如分析程序中某个被多次调用的程序段执行时间以优化程序),因为毕竟高性能频率记数的理论可以达到微秒级别。timer控件虽然精度比上面两者差很多,但是它使用方便,在要求不高的场合它还是最佳选择