客户端时间如何与服务器时间同步(多层架构系统理应如此)
多层系统开发,如何保持客户端与数据库或应用服务器时间同步是一个必须解决的问题 ,我发现许多系统取得是客户端的本地时间,造成多个客户端同时操作却时间不一样。而许多人采用频繁从数据库中取值的形式,增加服务器负载压力。当然有人说,数据保存的时候应该取数据库中时间 ,不错,但是涉及到本地数据之间的校验这类的操作,你该不会频繁地去数据库中得时间吧。鉴于此,本文利用windows系统的一个Api函数进行时间同步 。具体参下面类:(Delphi语法实现,当然)
*******调用--------------
var
myDateTime : TmyDateTime; //全局变量,供整个工程使用
//----------------------------------------------------
Procedure InitialDateTimeWhenSystemStart;//------系统启动的时候进行初始化
begin
myDateTime := TmyDateTime.Create;
//getServerDateTimeStr是从服务器取得的14位时间字符串
myDateTime.AppserverDataTimeStr := getServerDateTimeStr ;
myDateTime.InitialDateTimeSpan;//初始化
end;
//-----------------------------------------------------------
TmyDateTime = class
private
// FDateTimeInterval: Double;
FDateTimeInterval: TDateTime;
FAppserverDataTimeStr: string;
FServerDateTime: TDateTime; //第一次登录服务器的时间
FSysTickCount: Double;
procedure SetDateTime;
function GetDateTime_: TDateTime;
public
constructor create;
procedure InitialDateTimeSpan;
//---初始化本地时间与系统时间的间隔
property CurrentDataTime: TDateTime read GetDateTime_;
property AppserverDataTimeStr: string read FAppserverDataTimeStr write FAppserverDataTimeStr;
end;
implement
{ TmyDateTime }
function TmyDateTime.GetDateTime_: TDateTime;
var
FSysTickCount_: Double;
begin
FSysTickCount_ := GetTickCount;
Result := FServerDateTime + (FSysTickCount_ - FSysTickCount) / (24 * 60 * 60 * 1000);
{ if FDateTimeInterval < 0 then
Result := (Now - FDateTimeInterval)
else
Result := (Now + FDateTimeInterval); }
end;
procedure TmyDateTime.InitialDateTimeSpan;
//---初始化本地时间与系统时间的间隔
var
wYear, wMonth, wDay, wHour, wMinute, wSecond, wMili: word;
begin
try
wYear := StrToInt(copy(FAppserverDataTimeStr, 1, 4));
wMonth := StrToInt(Copy(FAppserverDataTimeStr, 5, 2));
wDay := StrToInt(copy(FAppserverDataTimeStr, 7, 2));
wHour := StrToInt(copy(FAppserverDataTimeStr, 9, 2));
wMinute := StrToInt(copy(FAppserverDataTimeStr, 11, 2));
wSecond := StrToInt(copy(FAppserverDataTimeStr, 13, 2));
wMili := 100;
FServerDateTime := EncodeDateTime(wYear, wMonth, wDAy, wHour, wMinute, wSecond, wMili);
FSysTickCount := GetTickCount;
// FDateTimeInterval := MilliSecondSpan(Now, FServerDateTime);
//FDateTimeInterval := Now - FServerDateTime;
except
// FDateTimeInterval := 0;
end;
end;
procedure TmyDateTime.SetDateTime;
var
wyear, wmonth, wday, whour, waminute, wsecond, wmilisencond: word;
smonth, sday, shour, saminute, ssecond: string;
ExactDateTime: TDateTime;
FSysTickCount_: Double;
begin
//ExactDateTime := FloatToDateTime(Now + FDateTimeInterval);
{if FDateTimeInterval < 0 then
ExactDateTime := (Now - FDateTimeInterval)
else
ExactDateTime := (Now - FDateTimeInterval); }
// ExactDateTime := (Now - FDateTimeInterval);
FSysTickCount_ := GetTickCount;
ExactDateTime := FServerDateTime + (FSysTickCount_ - FSysTickCount) / (24 * 60 * 60 * 1000);
DecodeDateTime(ExactDateTime, wyear, wmonth, wday, whour, waminute, wsecond, wmilisencond);
sMonth := IntToStr(wMonth);
if Length(sMonth) < 2 then sMonth := '0' + sMonth;
sday := IntToStr(wday);
if Length(sday) < 2 then sday := '0' + sday;
shour := IntToStr(whour);
if Length(shour) < 2 then shour := '0' + shour;
saminute := IntToStr(waminute);
if Length(saminute) < 2 then saminute := '0' + saminute;
ssecond := IntToStr(wsecond);
if Length(ssecond) < 2 then ssecond := '0' + ssecond;
FAppserverDataTimeStr := IntToStr(wyear) + smonth + sday + shour + saminute + ssecond; //smilisencond;
end;