Board index » delphi » Obtaining server time

Obtaining server time

The DOS command that has worked for me is:

   net time ServerName /set /yes

All you have to do is encapsulate this in Delphi, here's one way to do it:
SrvrName is the name of the computer you have a connection to, this is the
name that you see on the Network Neighborhood when looking for different
computers.  This sets your computer to that of the other computer, which
doesn't have to be actually a server in a real sense.  This has worked in
peer to peer as well as NT workgroups.  In some windows 98 early releases,
there could be some problems with net time.

procedure SynchronizeTime(SrvrName:String);
var i:integer;
begin
  WinExecAndWait32('net time ' + SrvrName +' /set /yes', 0);
end;

And here is a code snippet for WinExecAndWait32
/// Execute and wait till end of any command line program or applications
function WinExecAndWait32(CommandName:String; Visibility : integer):integer;
var
  zAppName:array[0..512] of char;
  zCurDir:array[0..255] of char;
  WorkDir:String;
  StartupInfo:TStartupInfo;
  ProcessInfo:TProcessInformation;
begin
  StrPCopy(zAppName,CommandName);
  GetDir(0,WorkDir);
  StrPCopy(zCurDir,WorkDir);
  FillChar(StartupInfo,Sizeof(StartupInfo),#0);
  StartupInfo.cb := Sizeof(StartupInfo);
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow := Visibility;
  if not CreateProcess(nil,
    zAppName,                      { pointer to command line string }
    nil,                           { pointer to process security
attributes }
    nil,                           { pointer to thread security attributes }
    false,                         { handle inheritance flag }
    CREATE_NEW_CONSOLE or          { creation flags }
    NORMAL_PRIORITY_CLASS,
    nil,                           { pointer to new environment block }
    nil,                           { pointer to current directory name }
    StartupInfo,                   { pointer to STARTUPINFO }
    ProcessInfo) then Result := -1 { pointer to PROCESS_INF }
  else begin
    WaitforSingleObject(ProcessInfo.hProcess,INFINITE);
    GetExitCodeProcess(ProcessInfo.hProcess,Result);
  end;
end;

Quote
Peter Crain <pcr...@compudoc.au.com> wrote in message

news:38b9c055.1046398@forums.inprise.com...
Quote
> Hello

> Some of users can have their workstation system clocks 2 days slow,
> which means records posted to the Pdx 'server' are unreliable.  Is
> there a BDE API call that returns the server's time?

> Systems are frequently mixed NT\95\98 so we can't rely on an NT API
> call.

> Regards & TIA

> Peter Crain

 

Re:Obtaining server time


oops! sorry for the extra declaration of
var i:integer;

I have cleaned out the other code which I have pasted and missed to erase
the declaration which I use in my own code.  The WinExecAndWait32 function,
is the whole unedited, cut & paste which I got from code central.

Re:Obtaining server time


I have used the code to synchronize all my users once they connect to a
multi-user shared database on a LAN.  I used time to synchornize the updates
on each of the local tables on my connected users. In this example, I just
pass the actual filename of the database table, and then the routine will
parse out the server name, and then synchronize the time with it.  My
program will assume the time of the computer storing the shared databases.
But after my program exits, I resume the time.  The technique is to store
the local time, and the tickcount, and upon exit of the program restore it
by adding the stored local time before synchronization to that of the end
tickcount minus the initial tickcount at the start.  There are other better
time servers if you have 24-hr online internet connection. There are also
time server programs freebies. And here is the actual implementation that I
experimented in one of my projects:

procedure TGlobalForm.SynchronizeTime(var ProjectFileName:String);
var SrvrName:string;
    i:integer;
begin
  SrvrName:=ExpandUNCFileName(ProjectFileName);
  if not (SrvrName[1]='\') then begin
    exit;
  end;
  if not FileExists(SrvrName) then begin
    ShowMessage('The host computer '+SrvrName+' is no longer connected.');
    exit;
  end;
  /// networked computer
  i:=3;while (SrvrName[i]<>'\') and (i<250) do inc(i);
  SrvrName:=Copy(SrvrName,1,i-1);
  WinExecAndWait32('net time ' + SrvrName +' /set /yes', 0);
  LocalTimeChanged:=true;
end;

LocalTimeChanged is my global var accessible by all of my forms.

Re:Obtaining server time


Hello

Some of users can have their workstation system clocks 2 days slow,
which means records posted to the Pdx 'server' are unreliable.  Is
there a BDE API call that returns the server's time?

Systems are frequently mixed NT\95\98 so we can't rely on an NT API
call.

Regards & TIA

Peter Crain

Re:Obtaining server time


Sorry, but your email address bounced back to me. So I have posted it here.

My oroginal code compiled well with Delphi 2 and 3. The reason why it failed
in D5 is could be due to differences in handling the GetExitCodeProcess,
which would require a type DWORD for the last parameter.

How about trying this instead. This one compiled fine with D5. Instead of
WinExecAndWait32, use this procedure:

procedure WinExec32(CommandLine:string);
var fndesc:string;
    StartInfo:TStartupInfo;
    ProcInfo: TProcessInformation;
begin
  FillChar(StartInfo,SizeOf(StartInfo),0);
  StartInfo.cb:=SizeOf(StartInfo);
  CreateProcess(nil,PChar(CommandLine),nil,nil,False,0,nil,nil,
        StartInfo,ProcInfo);
end;

To use the above procedure to synchronize time, call:
  WinExec32('net time ' + SrvrName +' /set /yes', 0);

where SrvrNane should have been declared as string elsewhere in your code as
in my sample:
procedure TGlobalForm.SynchronizeTime(var ProjectFileName:String);
var SrvrName:string;
    i:integer;
begin
  SrvrName:=ExpandUNCFileName(ProjectFileName);
  if not (SrvrName[1]='\') then begin
    exit;
  end;
  if not FileExists(SrvrName) then begin
    ShowMessage('The host computer '+SrvrName+' is no longer connected.');
    exit;
  end;
  /// networked computer
  i:=3;while (SrvrName[i]<>'\') and (i<250) do inc(i);
  SrvrName:=Copy(SrvrName,1,i-1);
  WinExec32('net time ' + SrvrName +' /set /yes', 0);
  LocalTimeChanged:=true;
end;

Quote
----- Original Message -----
From: Ian Robinson <i...@fourx4.demon.co.uk>
To: Joe Real <ngen...@thegrid.net>
Sent: Monday, February 28, 2000 1:46 AM
Subject: Re: Obtaining server time

> Joe

> Forgive the intrusion but I have been evesdropping on your replies about
ServerTime
> and decided to try your solution.

> I am having a problem with the WinExecandWait32 bit which will not compile
in D5. It
> stops at the line

> GetExitCodeProcess(ProcessInfo.hProcess,Result);

> with the message

> Types of actual and formal var parameters must be identical

> Any ideas please ?

> Regards
> Ian Robinson    Forest Land Rovers and Forest Software
>                 + 44 (0)1594 822606 voice,
>                 + 44 (0)1594 822634 fax
>                 + 44 (0)7718 806006 mobile

Re:Obtaining server time


I have another method - run a "time server" such as AboutTime
(http://www.arachnoid.com/abouttime/) on your server and use a SNTP (simple
network time protocol) component to retrieve the time from the server. One
such component is in the latest Winshoes beta (v. 7.039b,
http://www.pbe.com/Winshoes/). Make sure you set the "time out" property -
some time servers don't respond promptly under all situations.

If you have an "always-on" internet connection, you can even get the current
time from public time servers such as Nasa (ns.arc.nasa.gov).

brian

Quote
"Peter Crain" <pcr...@compudoc.au.com> wrote in message

news:38b9c055.1046398@forums.inprise.com...
Quote
> Hello

> Some of users can have their workstation system clocks 2 days slow,
> which means records posted to the Pdx 'server' are unreliable.  Is
> there a BDE API call that returns the server's time?

> Systems are frequently mixed NT\95\98 so we can't rely on an NT API
> call.

> Regards & TIA

> Peter Crain

Re:Obtaining server time


Quote
> To use the above procedure to synchronize time, call:
>   WinExec32('net time ' + SrvrName +' /set /yes', 0);

Take out the last parameter in the modified code. Should have been:
   WinExec32('net time ' + SrvrName +' /set /yes');

Sorry.

Other Threads