本文整理自网络,侵删。
一、服务器与客户端的时间同步
我们在编程时,需要让客户端与服务器的时间保存一致(同步),这样,对于数据的查询和处理很有必要。比如,防止用户修改当前时间,造成数据逻辑混乱,客户端使用的时间应为服务器时间。
如何处理呢,我们可以使用Delphi Indy组件中的 TIdDayTimeServer和TIdDayTime一对组件。
TIdDayTimeServer用于服务器端,TIdDayTime用于客户端,二级控件只要参数配置好,随时可以校准二者的时间。
只要我们在客户端,通过Timer定时,读取服务器时间,并保持一致。
二、技术准备
1、在服务器端加入TIdDayTimeServer,大多数使用默认参数。
(1)IdDayTimeServer1.DefaultPort
默认端口:1339(通常默认值)
(2)IdDayTimeServer1.Active
True,启动IdDayTimeServer。
False,关闭IdDayTimeServer。
2、在客户端加入TIdDayTimeServer,大多数使用默认参数。
(1)IdDayTime1.Host
服务器IP地址,
(2) IdDayTime1.Port
服务器端口:与服务器端一致。
(3)IdDayTime1.DayTimeStr
返回时间字符串,格式如下:
“星期六, 十月 06, 2018 12:26:27-EST”
这是正常返回的值,通过分析此格式,通过由该字符串,获取相关日期时间的值。
3、SetLocalTime(SysTime) ,设置本地时间(API)
4、系统时间参数,TSystemTime类型,用于设置本地时间,它的数据结构如下:
TSystemTime = record
wYear: Word;
wMonth: Word;
wDayOfWeek: Word;
wDay: Word;
wHour: Word;
wMinute: Word;
wSecond: Word;
wMilliseconds: Word;
end;
5、分解DayTimeStr获取,标准时间值函数
CopyDateTime(S) // 代码参见下文
三、代码如下:
1、服务器
procedure TForm1.Button1Click(Sender: TObject);begin IdDayTimeServer1.DefaultPort := StrToIntDef(Edit1.Text, strtoint(Edit1.Text)); IdDayTimeServer1.Active := True; Memo1.Lines.Add('服务器启动成功');end; procedure TForm1.Button2Click(Sender: TObject);begin IdDayTimeServer1.Active := false; Memo1.Lines.Add('服务器连接断开!');end;2、客户端
function TForm1.CopyDateTime(TimeStr:string):String; // CopyDateTimevar SysTime: TSystemTime; tzInfo: Time_Zone_Information; // 系统参数 hBias, // 小时 偏差 mBias, // 分钟 偏差 First,Last,Top: Integer; S:string; i,iYear,iMonth,iDay,iH,iM,iSS:integer; begin // 星期六, 十月 06, 2018 12:26:27-EST 格式// 1 2 3 4 5 6 7 8 子串序号 Result:=''; iYear:=0; iMonth:=0; iDay:=0; iH:=0; iM:=0; iSS:=0; if Length(TimeStr)>30 then begin First:=0; // 字符首位 Last:=0; // 字符未位 Top:=0; // 字符序列号 for i:=1 to Length(TimeStr) do begin if (TimeStr[i]=' ') or (TimeStr[i]=',') or (TimeStr[i]=':') or (TimeStr[i]='-') or (i=Length(TimeStr)) then // 断点 begin First:=Last+1; Last:=i; if i<Length(TimeStr) then S:=Copy(TimeStr,First,Last-First) // 获取一字符 else S:=Copy(TimeStr,First,Last-First+1); // 包含最后字符 S:=Trim(S); // 取消两端空格 if S<>'' then begin Top:=Top+1;// showmessage(IntToStr(Top)+': '+S); if Top=2 then // 处理月 begin if (S='一月') or (S='Jan') then iMonth:=1; if (S='二月') or (S='Feb') then iMonth:=2; if (S='三月') or (S='Mar') then iMonth:=3; if (S='四月') or (S='Apr') then iMonth:=4; if (S='五月') or (S='May') then iMonth:=5; if (S='六月') or (S='Jun') then iMonth:=6; if (S='七月') or (S='Jul') then iMonth:=7; if (S='八月') or (S='Aug') then iMonth:=8; if (S='九月') or (S='Sep') then iMonth:=9; if (S='十月') or (S='Oct') then iMonth:=10; if (S='十一月') or (S='Nev') then iMonth:=11; if (S='十二月') or (S='Dec') then iMonth:=12; end; if Top=3 then // 处理日 iDay:=StrToInt(S); if Top=4 then // 处理年 iYear:=StrToInt(S); if Top=5 then // 处理时 iH:=StrToInt(S); if Top=6 then // 处理分 iM:=StrToInt(S); if Top=7 then // 处理秒 iSS:=StrToInt(S); end; end; end; end;// 下面分别向SysTime分解字符串的值 SysTime.wYear:=iYear; SysTime.wMonth:=iMonth; SysTime.wDay:=iDay; SysTime.wHour:=iH; SysTime.wMinute:=iM; SysTime.wSecond:=iSS; SysTime.wMilliseconds:=0;// 对获取的SysTime时间值 进行修正 SysTime.wYear:=SysTime.wYear; // 加入日期偏差 SysTime.wHour:=SysTime.wHour-hBias; // 加入小时偏差 SysTime.wMinute:=SysTime.wMinute-mBias; // 加入小时偏差 Result:=FormatDateTime('yyyy-mm-dd hh:nn:ss zzz',SystemTimeToDateTime(SysTime));end; procedure TForm1.Button1Click(Sender: TObject);begin IdDayTime1.Host := Edit1.Text; // 连接主机 IdDayTime1.Port := StrToIntDef(Edit2.Text,strtoint(Edit2.Text)); // 端口end; procedure TForm1.Button2Click(Sender: TObject);var sDateTime:string; DateTime:TDateTime; SystemTime: TSystemTime;begin DateSeparator:='-'; ShortDateFormat:='yyyy-MM-dd'; LongDateFormat:='yyyy''年'',MM''月'',dd''日'''; TimeSeparator:=':'; sDateTime:=IdDayTime1.DayTimeStr; sDateTime:=CopyDateTime(sDateTime); Edit4.Text:=sDateTime; DateTime:=StrToDateTime(SDateTime); // 获得时间(TDateTime格式) DateTimeToSystemTime(DateTime,systemtime); // TDateTime格式转化TSystemTime SetLocalTime(SystemTime); // 设置系统时间 GetLocalTime(SystemTime); // 读取系统时间 DateTime:=SystemTimeToDateTime(systemtime); // TSystemTime格式转化TDateTime Edit5.Text:=DateTimetoStr(DateTime);end; procedure TForm1.Timer1Timer(Sender: TObject); // 定时同步 var sDateTime:string; DateTime:TDateTime; SystemTime: TSystemTime; begin sDateTime:=IdDayTime1.DayTimeStr; sDateTime:=CopyDateTime(sDateTime); DateTime:=StrToDateTime(SDateTime); // 获得时间(TDateTime格式) DateTimeToSystemTime(DateTime,systemtime); // TDateTime格式转化TSystemTime格式 SetLocalTime(SystemTime); // 设置系统时间 StatusBar1.Panels[1].Text:='校正时间:'+sDateTime;end; procedure TForm1.CheckBox1Click(Sender: TObject);begin if CheckBox1.Checked then begin Button1Click(Sender); Timer1.Enabled:=True; end else Timer1.Enabled:=False;end;
――――――――――――――――
原文链接:https://blog.csdn.net/lyhoo163/article/details/82950824
相关阅读 >>
Delphi 快速获取文件大小(使用_lopen和fileseek,此函数可以快速获取文件大小,即使文件已经被其它程序锁定)
更多相关阅读请进入《Delphi》频道 >>