客户端时间如何与服务器时间同步(多层架构系统理应如此) 多层系统开发,如何保持客户端与数据库或应用服务器时间同步是一个必须解决的问题 ,我发现许多系统取得是客户端的本地时间,造成多个客户端同时操作却时间不一样。而许多人采用频繁从数据库中取值的形式,增加服务器负载压力。当然有人说,数据保存的时候应该取数据库中时间 ,不错,但是涉及到本地数据之间的校验这类的操作,你该不会频繁地去数据库中得时间吧。鉴于此,本文利用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;

|