关于NTP时间格式
求时间服务器时间组织成NTP格式发送给客户端的代码.
[解决办法]
const maxint2 = 4294967296.0;function tzbias : double; // 获取本地时间区与UTC时间偏差;var tz : TTimeZoneInformation;begin GetTimeZoneInformation(tz); result := tz.Bias / 1440;end;procedure dt2ntp(dt : tdatetime; var nsec, nfrac : longint); var d, d1 : double;begin d := dt + tzbias - 2; d := d * 86400; d1 := d; if d1 > maxint then begin d1 := d1 - maxint2; end; nsec := trunc(d1); d1 := ((frac(d) * 1000) / 1000) * maxint2; if d1 > maxint then begin d1 := d1 - maxint2; end; nfrac := trunc(d1);end;// 将NTP 时间戳(timestamp)格式转换成为DELPHI的 TDateTime 格式;function ntp2dt(nsec, nfrac : longint) : tdatetime;var d, d1 : double;begin d := nsec; if d < 0 then d := maxint2 + d - 1; d1 := nfrac; if d1 < 0 then d1 := maxint2 + d1 - 1; d1 := d1 / maxint2; d1 := trunc(d1 * 1000) / 1000; result := (d + d1) / 86400; result := result - tzbias + 2;end;
[解决办法]
//==============================================================================
//Ntp.将DELPHI的 TDateTime 格式转换成为 NTP 时间戳(timestamp)格式***************
//==============================================================================
procedure DateTimeToNtp(DateTime: TDateTime; var NtpSec, NtpFrac: LongInt);
var DateTime1, DateTime2: Double;
begin
DateTime1 := DateTime + GetTimeZoneBias - 2;
DateTime1 := DateTime1 * 86400;
DateTime2 := DateTime1;
if DateTime2>MaxInt then DateTime2 := DateTime2 - MAXUINT2;
NtpSec := Trunc(DateTime2);
DateTime2 := ((Frac(DateTime1) * 1000) / 1000) * MAXUINT2;
if DateTime2>MaxInt then DateTime2 := DateTime2 - MAXUINT2;
NtpFrac := Trunc(DateTime2);
end;
//==============================================================================
//Ntp.将 NTP 时间戳(timestamp)格式转换成为DELPHI的 TDateTime 格式***************
//==============================================================================
function NtpToDateTime(const NtpSec, NtpFrac: LongInt): TDateTime;
var DateTime1, DateTime2: Double;
begin
DateTime1 := NtpSec;
if DateTime1<0 then DateTime1 := MAXUINT2 + DateTime1 - 1;
DateTime2 := NtpFrac;
if DateTime2<0 then DateTime2 := MAXUINT2 + DateTime2 - 1;
DateTime2 := DateTime2 / MAXUINT2;
DateTime2 := Trunc(DateTime2 * 1000) / 1000;
Result := (DateTime1 + DateTime2) / SecsPerDay;
Result := Result - GetTimeZoneBias + 2;
end;