第一种方法,通过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版本有关就不知道了。