【Delphi】获取网络时间的两种方法

第一种方法,通过indy 控件来获取。

{
可用时间服务器
cn.pool.ntp.org
203.107.6.88
time.pool.aliyun.com
ntp1.aliyun.com
ntp2.aliyun.com
ntp3.aliyun.com
ntp4.aliyun.com
ntp5.aliyun.com
ntp6.aliyun.com
ntp7.aliyun.com
time1.aliyun.com
time2.aliyun.com
time3.aliyun.com
time4.aliyun.com
time5.aliyun.com
time6.aliyun.com
time7.aliyun.com
}
uses
  IdSNTP,
  ......

function GetNetTime(host : string): TDateTime;
var
  Sntp: TIdSNTP;
begin
  try
    Sntp := TIdSNTP.Create(nil);
    try
      Sntp.Host := host;
      Sntp.Active := True;
      Result := Sntp.DateTime;
      Sntp.Active := False;
      Sntp.Disconnect;
    except on E: Exception do
      begin
         Sntp.Active := False;
         Sntp.Disconnect;
         Exit(0);
      end;
    end;
  finally
    Sntp.Free;
  end;

end;

第二种方法,通过HTTP控件获取。

//淘宝正常返回:{"api":"mtop.common.getTimestamp","v":"*","ret":["SUCCESS::接口调用成功"],"data":{"t":"1613698172343"}}
//苏宁正常返回:{"sysTime2":"2021-02-19 10:00:31","sysTime1":"20210219100031"}
//京东正常返回:{"serverTime":1613702035917}
function GetRealTime1: TDateTime;
const
  TB_HOST = 'http://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp';
  SN_HOST = 'http://quan.suning.com/getSysTime.do';
  JD_HOST = 'https://a.jd.com//ajax/queryServerData.html';
var
  HTTP    : TNetHTTPClient;
  TM      : TMemoryStream;
  B       : TBytes;
  S       : string;
  jo      : TJSONObject;
  jv      : TJSONString;
  FormatSettings: TFormatSettings;
  T : TDateTime;
  i : Int64;
begin
  Result := 0;
  TM   := TMemoryStream.Create;
  HTTP := TNetHTTPClient.Create(nil);
  try
    HTTP.ConnectionTimeout := 2000;  //连接超时设置为 2秒
    HTTP.ResponseTimeout   := 2000;     //读取超时设置为 2秒

    HTTP.Get(TB_HOST,TM);     //首先检查 淘宝网络
    SetLength(B,TM.Size);
    TM.Position := 0;
    TM.Read(B[0],TM.Size);
    S := TEncoding.UTF8.GetString(B);  //取得实际的时间字符串
    //解析字符串
    jo := TJSONObject.ParseJSONValue(S) as TJSONObject;
    try
      if jo.TryGetValue('data',jo) then
       if jo.TryGetValue('t',jv) then
          begin
            S := jv.Value;
            i := StrToInt64Def(S,0) div 1000;
            //相差8个小时
            T := IncHour(UnixToDateTime(i), 8);
            Exit(T);
          end;
    finally
      if jo <> nil then
         jo.Free;
    end;


    //2. 解析京东
    HTTP.Get(JD_HOST,TM);     //京东
    SetLength(B,TM.Size);
    TM.Position := 0;
    TM.Read(B[0],TM.Size);
    S := TEncoding.UTF8.GetString(B);  //取得实际的时间字符串
    //解析字符串
    jo := TJSONObject.ParseJSONValue(S) as TJSONObject;
    try
      if jo.TryGetValue('serverTime',jv) then
        begin
          S := jv.Value;
          i := StrToInt64Def(S,0) div 1000;
          //相差8个小时
          T := IncHour(UnixToDateTime(i), 8);
          Exit(T);
        end;
    finally
      if jo <> nil then
         jo.Free;
    end;



    //如果解析失败等,则尝试苏宁
    HTTP.Get(SN_HOST,TM);     //二次检查 苏宁网络
    SetLength(B,TM.Size);
    TM.Position := 0;
    TM.Read(B[0],TM.Size);
    S := TEncoding.UTF8.GetString(B);  //取得实际的时间字符串

    jo := TJSONObject.ParseJSONValue(S) as TJSONObject;
    try
      if jo.TryGetValue('sysTime2',jv) then
       begin
        S := jv.Value;
        FormatSettings := TFormatSettings.Create;
        FormatSettings.ShortDateFormat := 'YYYY-MM-DD';
        FormatSettings.LongDateFormat  := 'YYYY-MM-DD';
        FormatSettings.DateSeparator   := '-'  ;   //日期分隔符
        FormatSettings.LongTimeFormat  := 'hh:mm:ss';
        FormatSettings.ShortTimeFormat := 'hh:mm:ss';
        FormatSettings.TimeSeparator   := ':';   //时间分隔符
        try
          Result := StrToDateTime(S,FormatSettings);
        except on E: Exception do
          Result := 0;
        end;
       end;
    finally
      if jo <> nil then
         jo.Free;
    end;


  finally
    HTTP.Free;
    TM.Free;
  end;
end;

两种方法对比,我是在Berlin版本上使用,经过测试,第一种方法经常会造成程序死机,无法正确读取到时间,第二种方法稳定可靠。是否和Indy版本有关就不知道了。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海纳老吴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值