频道分类

Delphi 操作系统时间与Web标准时间校正

作者:admin 来源: 日期:2020/2/5 8:56:53 人气: 标签:

 
本文编译的程序代码全部原码下载: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中,通过。成功取决于网站的返回率。

 另外,考虑到访问网站获取时间值到修改本地时间,有几秒钟的误差,设置本地时间时,应加上误差值。
————————————————

原文链接:https://blog.csdn.net/lyhoo163/article/details/82943440