网络校时程序
因本人计算机cmos电池缺点,系统时间每次开机都丢失,所以我就想通过网络来及时调整自己的时间。
起初我从网络上搜索到很多类似的软件,但他们都附带其他我并不想用的功能。所以我决定自己去做一个只校时的软件。
首先,需要寻找一个稳定快捷的网络时间服务器,这是至关重要的,否则这个程序将失去他的价值。搜索结果很多,不过好多都延时厉害,有些还可能造成程序陷入假死状态。因而我从同类软件中找寻他们所使用的服务器地址,这样经过实践考验的地址应该比自己盲目搜索的质量要好的多。
另外,在本程序制作过程中,我采用控制台类型的程序以减少程序所占空间,同时也为了提高程序运行效率,降低本程序运行所带来的延时。
而且本程序除了联络网络时间服务器,返回结果分析其编码后及时校正本地时间后立马退出,决不驻留内存。
以下为代码:
program g_time;
{$APPTYPE CONSOLE}
uses
SysUtils,windows,
Variants,Classes,
Sockets;
{
网络校时程序
作者:qinchina
原理:通过udp的13端口号方式访问网络时间服务器
发送‘<本地主机地址’到网络服务器
返回时间格式为‘17 FEB 2008 14:25:35 HKT’
对返回的数据解码出日期格式并矫正本地时间
时间:2008-2-18 10:44:50
提示:本程序对时间校对忽略网络延时及本程序运行延时
}
var udp:TUdpSocket;
itime,y,m,d,t:string;
i:integer;
dtime:Tdatetime;
stime:TSystemTime;
const host:String='203.129.68.14'; //网络时间服务器地址
const month:array[1..12] of string =('JAN','FEB','MAR','APR','MAY','JUN','JUL','AUG','SEP','OCT','NOV','DEC');
begin
{ TODO -oUser -cConsole Main : Insert code here }
udp:=TUdpSocket.Create(nil);
udp.LocalPort :='13';
udp.RemoteHost :=host;
udp.RemotePort :='13'; //设定udp连接组件属性
try
udp.Connect;
udp.Sendln('<'+udp.LocalHostAddr);
itime:=udp.Receiveln();
finally
udp.Free ;
end;
if itime<>'' then
begin
d:=copy(itime,1,2);//获取日期
m:=copy(itime,4,3);//获取月份
y:=copy(itime,8,4);//获取年份
t:=copy(itime,13,8);//获取时间
i:=1;
while month[i]<>m do i:=i+1;//把英文缩写的月份转化为数字月份
m:=inttostr(i);
itime:=y+'-'+m+'-'+d+' '+t; //格式化时间字符串
dtime:=strtodatetime(itime); //转化为时间类型
datetimetosystemtime(dtime,stime); //转化为系统时间类型
setlocaltime(stime); //设定本地系统时间
end;
end.
后来我从网络上下载了kol包,重新用此包制作了窗口程序。
{ KOL MCK } // Do not remove this line!
{$DEFINE KOL_MCK}
unit ugettime;
interface
{$IFDEF KOL_MCK}
uses Windows, Messages, KOL {$IF Defined(KOL_MCK)}{$ELSE}, mirror, Classes, Controls, mckCtrls, mckObjs, Graphics {$IFEND (place your units here->)};
{$ELSE}
{$I uses.inc}
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
{$ENDIF}
type
{$IF Defined(KOL_MCK)}
{$I MCKfakeClasses.inc}
{$IFDEF KOLCLASSES} {$I Tfrm_gettimeclass.inc} {$ELSE OBJECTS} Pfrm_gettime = ^Tfrm_gettime; {$ENDIF CLASSES/OBJECTS}
{$IFDEF KOLCLASSES}{$I Tfrm_gettime.inc}{$ELSE} Tfrm_gettime = object(TObj) {$ENDIF}
Form: PControl;
{$ELSE not_KOL_MCK}
Tfrm_gettime = class(TForm)
{$IFEND KOL_MCK}
KOLProject1: TKOLProject;
KOLForm1: TKOLForm;
Timer1: TKOLTimer;
BitBtn1: TKOLBitBtn;
Label1: TKOLLabel;
Label2: TKOLLabel;
procedure Timer1Timer(Sender: PObj);
procedure BitBtn1Click(Sender: PObj);
procedure KOLForm1Show(Sender: PObj);
private
{ Private declarations }
public
{ Public declarations }
end;
var
frm_gettime {$IFDEF KOL_MCK} : Pfrm_gettime {$ELSE} : Tfrm_gettime {$ENDIF} ;
{$IFDEF KOL_MCK}
procedure Newfrm_gettime( var Result: Pfrm_gettime; AParent: PControl );
{$ENDIF}
implementation
uses sockets,sysutils;
{$IF Defined(KOL_MCK)}{$ELSE}{$R *.DFM}{$IFEND}
{$IFDEF KOL_MCK}
{$I ugettime_1.inc}
{$ENDIF}
{
网络校时程序
作者:qinchina
原理:通过udp的13端口号方式访问网络时间服务器
发送‘<本地主机地址’到网络服务器
返回时间格式为‘17 FEB 2008 14:25:35 HKT’
对返回的数据解码出日期格式并矫正本地时间
时间:2008-2-18 10:44:50
提示:本程序对时间校对忽略网络延时及本程序运行延时
}
var time_count:integer;
procedure Tfrm_gettime.Timer1Timer(Sender: PObj);
begin
label2.caption:='离本程序自动关闭还剩'+inttostr(time_count)+'秒...';
if time_count=0 then
begin
timer1.enabled:=false;
frm_gettime.Form.Close();
exit;
end;
dec(time_count);
end;
procedure Tfrm_gettime.BitBtn1Click(Sender: PObj);
begin
frm_gettime.Form.Close();
end;
procedure Tfrm_gettime.KOLForm1Show(Sender: PObj);
var udp:TUdpSocket;
itime,y,m,d,t:string;
i:integer;
dtime:Tdatetime;
stime:TSystemTime;
const host:String='203.129.68.14'; //网络时间服务器地址
const month:array[1..12] of string =('JAN','FEB','MAR','APR','MAY','JUN','JUL','AUG','SEP','OCT','NOV','DEC');
begin
udp:=TUdpSocket.Create(nil);
udp.LocalPort :='13';
udp.RemoteHost :=host;
udp.RemotePort :='13'; //设定udp连接组件属性
try
udp.Connect;
udp.Sendln('<'+udp.LocalHostAddr);
itime:=udp.Receiveln();
finally
udp.Free ;
end;
if itime<>'' then
begin
d:=copy(itime,1,2);//获取日期
m:=copy(itime,4,3);//获取月份
y:=copy(itime,8,4);//获取年份
t:=copy(itime,13,8);//获取时间
i:=1;
while month[i]<>m do i:=i+1;//把英文缩写的月份转化为数字月份
m:=inttostr(i);
itime:=y+'-'+m+'-'+d+' '+t; //格式化时间字符串
dtime:=strtodatetime(itime); //转化为时间类型
datetimetosystemtime(dtime,stime); //转化为系统时间类型
setlocaltime(stime); //设定本地系统时间
end;
label1.Caption :='本地系统时间与网络同步成功完成!';
time_count:=10;
timer1.enabled:=true;
end;
end.
工程文件为:
{ KOL MCK } // Do not remove this line!
program gettime;
uses
KOL,
ugettime in 'ugettime.pas' {frm_gettime};
{$R *.res}
begin // PROGRAM START HERE -- Please do not remove this comment
{$IF Defined(KOL_MCK)} {$I gettime_0.inc} {$ELSE}
Application.Initialize;
Application.Title := '网络校时';
Application.CreateForm(Tfrm_gettime, frm_gettime);
Application.Run;
{$IFEND}
end.