操作系统时间与Web标准时间校正
本文编译的程序代码全部原码下载:https://download.csdn.net/download/lyhoo163/10703510
一、获取标准时间的意义
我们在编程时,对于数据的核准,需要与日期时间值,作为校准参数。因此,客户端时间要与服务器时间一致,将它们的时间与标准时间一致,是最好的办法。通过访问网站:time.nist.gov,可以获取标准日期时间字符串,再对本地操作系统,进行时间同步操作。
使用Delphi的Indy组件中的TidDayTime控件,再做好日期时间值 的分解。方便实用,本程序同时,也是我们日常使用时,对操作系统,进行 日期时间校正的小工具。
二、技术准备
1、访问网站:time.nist.gov
2、系统时间参数,这一参数用于设置本地时间,它的类型结构如下:
TSystemTime = record
wYear: Word;
wMonth: Word;
wDayOfWeek: Word;
wDay: Word;
wHour: Word;
wMinute: Word;
wSecond: Word;
wMilliseconds: Word;
end;
3、 Time_Zone_Information 这是标准时间的参数
4、 GetTimeZoneInformation(tzInfo) 获取系统当地时间(时区设置)信息
5、TidDayTime控件,该控件可以指定Host,获取标准时间值(字符串),IdDayTime1.DayTimeStr,,该字符串值返回的三种形式(格式如下):
(1)58396 18-10-05 05:06:04 31 0 0 691.8 UTC(NIST) *
这是正常返回的值,通过分析此格式,通过由该字符串,获取相关日期时间的值。
(2)空串
这是未能获取时间值,要排除它。
(3)Access denied -- too many requests
这是访问太频繁,造成访问无效。要排除它。
特别提醒:该字符串,只能获取2位年的值各要加入千位值,如21世纪,就要加入2000.。
我测试过了XE10中的IdDayTime1.DayTimeStr,格式一样。这一字符串格式,是由time.nist.gov,约定返回的格式。当然我们要与它相对应,进行进行分解时间值了。
6、SetLocalTime(SysTime) ,设置本地时间(API)
7、GetLocalTime(SystemTime),获取本地系统时间(API)
三、实现代码如下
function TForm1.getDateTime(Host:string):string; // 与网络上获取时间并同步
var IdDayTime1: TIdDayTime;
tzInfo: Time_Zone_Information; // 系统参数
hBias, // 小时 偏差
mBias: Integer; // 分钟 偏差
TimeStr:String; // 时间字符
SysTime: TSystemTime; // TSystemTime 是系统定义的结构, 16 个字节:
function IsNumber(aVal: string): Boolean;
var
a:Integer;
begin
try
Result:=True;
a:=StrToInt(aVal);
except
Result:=False;
end;
end;
begin
GetTimeZoneInformation(tzInfo); // 获取系统当地时间(时区设置)信息
hBias:=tzInfo.Bias div 60; // 获取当地时区和格林威治的小时差
mBias:=tzInfo.Bias mod 60; // 获取当地时区和格林威治的分钟差
IdDayTime1:=TIdDayTime.Create(Application); // 创建IdDayTime
try
IdDayTime1.Host:=Host; // 从热点获取时间
TimeStr:=Trim(IdDayTime1.DayTimeStr); // 返回时间字符串
if Copy(TimeStr,1,6)='Access' then
begin
showMessage(' 访问频率太官密!');
exit;
end;
if TimeStr='' then
begin
showMessage('未获取网页时间!');
exit;
end;
// 下面分别向SysTime分解字符串的值
if IsNumber(Copy(TimeStr,1,5)) then
begin
SysTime.wYear:=StrToInt(Copy(TimeStr,7,2)); // 年度仅2位 21世纪要加入2000
SysTime.wMonth:=StrToInt(Copy(TimeStr,10,2));
SysTime.wDay:=StrToInt(Copy(TimeStr,13,2));
SysTime.wHour:=StrToInt(Copy(TimeStr,16,2));
SysTime.wMinute:=StrToInt(Copy(TimeStr,19,2));
SysTime.wSecond:=StrToInt(Copy(TimeStr,22,2));
SysTime.wMilliseconds:=StrToInt(Copy(TimeStr,32,3));
end;
except
Showmessage('从获取时间失败!');
Exit;
end;
// 对获取的SysTime时间值 进行修正
SysTime.wYear:=SysTime.wYear+2000; // 加入日期偏差
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
Edit1.Text:=getDateTime('time.nist.gov');
end;
procedure TForm1.Button2Click(Sender: TObject);
var systemtime:Tsystemtime;
DateTime:TDateTime;
begin
DateSeparator:='-';
ShortDateFormat:='yyyy-MM-dd';
LongDateFormat:='yyyy''年'',MM''月'',dd''日''';
TimeSeparator:=':';
DateTime:=StrToDateTime(Edit4.text); //获得时间(TDateTime格式)
DateTimeToSystemTime(DateTime,systemtime); //把Delphi的TDateTime格式转化为API的TSystemTime格式
SetLocalTime(SystemTime); //设置系统时间
GetLocalTime(SystemTime); //读取系统时间
DateTime:=SystemTimeToDateTime(SystemTime); //把API的TSystemTime格式 转化为 Delphi的TDateTime格式
Edit2.Text:=DateTimeToStr(DateTime)
end;
四、测试结果,D7和XE10.2中,通过。成功取决于网站的返回率。
另外,考虑到访问网站获取时间值到修改本地时间,有几秒钟的误差,设置本地时间时,应加上误差值。