Advertisement
2_2002-2004 Internet/ Browsers/ HTML #127866

PC CLOCK SYNCHRONIZING USING HTTP PROTOCOL

This article describes using Windows Internet API for atomic clock sites connection and synchronization PC clock. C++ code is included.

AI

AI Summary: This codebase represents a historical implementation of the logic described in the metadata. Our preservation engine analyzes the structure to provide context for modern developers.

Source Code
original-source
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=koi8-r">
<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
<title>Untitled Document</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<p align="center"><font color="#0000A0" size="4"><b>PC CLOCK SYNCHRONIZING USING 
 HTTP PROTOCOL<br>
 </b></font></p>
<p align="center"><font color="#0000A0" size="2"><b>by Alex Rest</b></font></p>
<p align="left"><u>Environment : </u>VC6, VC7, Windows 9x/NT/2000/XP with IE4 
 or higher</p>
<p><font color="#0000A0" size="4"><b>Introduction</b> </font></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The standard way of synchronization PC clock though
Internet is using special Network Time Protocol (NTP). It was
mainly developed at the Delaware University in the United States.
Tree versions of NTP were defined: the first on 1988, the second
on 1989, the third on 1992. The current version is the third that
is compatible with the previous ones. To make the use of NTP on
personal computers easier, on 1995 it was defined the Simplified
NTP (SNTP).<br>
Unfortunately standard windows software of Win95/98/ME/NT/W2KPro
is not support synchronization PC Clock using Internet.<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;When I solved to create synchronization program I chose
HTTP (Hypertext Transfer Protocol) instead SNTP. I like it
because it is more universal. All WWW pages that you watch are
brought to the screen of your PC using this protocol. I created
the program and called it &quot;For Atomic Synchronization&quot;.<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;There are a lot of government and scientific sites that
shows atomic time. There is small delay of site opening and
receiving information. I explore my program &quot;For Atomic
Synchronization&quot; during some month. Net delay seldom
overloads 2 seconds. I take half delay and correct time according
it. As result I cannot find difference between my PC clock time
and time that I watch on TV Screen ore hear in FM receiver. <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;As a time source I use site of Time Service Department
of U.S. Naval Observatory. It is official Source of Time for the
Department of Defense and the Standard of Time for the United
States. I have tested some others. They all works well but this
one have very simple format. The WWW page size is only 603
symbols (including html tags). Try this URL: <a
href="http://tycho.usno.navy.mil/cgi-bin/timer.pl">http://tycho.usno.navy.mil/cgi-bin/timer.pl</a>
and you will see same information as my program gets. </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;For Atomic Synchronization&quot; program is
big enough for describing. To demonstrate main principles of
synchronization I create small project that is described below.</p>
<p><font color="#0000A0" size="4"><b>Reading WWW sites using Win
API </b></font></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Modern Windows versions with Internet Explorer 4.0
or later have very nice Internet API functions. You need not work
with such low terms as TCP/IP protocol, sockets, ports, DNS, http
protocol and etc. In this example I use API functions instead
same MFC classes because they are more universal and you can easy
translate this code to VB ore to other program language.<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;All API functions work as chains. The first function
opens Windows resource and returns its number that is named
&quot;handle&quot;. Next function must use this handle. It could
return other handle, return code or something else. You mast
close handle when you need not it any more.</p>
<p>Look at the function CBSAtomicEduDlg::OnSyncro (see code
below). It works with Internet as user:<br>
1) Function InternetOpen is opens Internet. If you are off line
now it opens Dialup connection window.<br>
2) Function InternetOpenUrl retrieves the site that you are
looking for.<br>
3) Function InternetReadFile reads the site into the text buffer.<br>
</p>
<p>It is all! You have the text of site! Do with it that you
want!<br>
</p>
<p>And do not forget check errors and close handles (function
InternetCloseHandle). <br>
Such a way you can explore any information in Internet!</p>
<p>Do not forget to include in the project &quot;Wininet.h&quot;
file !</p>
<p><font color="#0000A0" size="4"><b>Universal and Local time</b></font></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;My watch show 02:00 am when there is midnight in
London. The sun is rolling around the Earth so there is different
time in different places. (P.s. I heard about Copernicus and
Jordano Bruno). To define what time we use in the place where we
are, we use special time zone. Time zones are not strips on a
globe. They were created not only according geographical
longitude but according states (countries) delimiters too. If you
want to synchronize your PC using Internet you must have right
zone information in your Operating System. You had set it while
was installing OS and can change any time later.<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If you know Universal time (GMT) and your time zone you
can ease calculate your local time. <br>
Look at function LocalZoneTime (see code bellow). It calculate
Universal time to Local time using time zone information.
Universal time I got from WWW site. All information about time
zone that I need I received by calling Win API function
GetTimeZoneInformation. Look at Microsoft help to understand how
use this information. The information includes DST (daylight
saving time) correction.</p>
<p><font color="#0000A0" size="4"><b>Links</b></font></p>
<p><a href="http://www.brigsoft.com/bsatomic/">http://www.brigsoft.com/bsatomic/</a>
- All around synchronization include link to this article,
project download links, &quot;For Atomic Synchronization&quot;
program download link and description.<br>
<a href="http://tycho.usno.navy.mil/cgi-bin/timer.pl">http://tycho.usno.navy.mil/cgi-bin/timer.pl</a>
- official Source of Time for the Department of Defense and the
Standard of Time for the United States.</p>
<p><font color="#0000A0" size="4"><strong>Source VC++ code</strong></font></p>
<p>It is a part of Dialog based MFC project, that makes time
synchronization.</p>
<p><font color="#008000" size="2" >// LocalZoneTime function
calculate Local time using Universal time.<br>
// Time zone information is gotten from Windows using <br>
// GetTimeZoneInformation API function (see MSDN for mo
information).<br>
// The function support DST time.<br>
// Created by Alex.</font><font size="2"><br>
void LocalZoneTime(const SYSTEMTIME&amp; tmUniversal,
SYSTEMTIME&amp; tmLocal)<br>
{</font></p>
<blockquote>
  <p><font size="2">TIME_ZONE_INFORMATION TZI;<br>
  DWORD retCode = GetTimeZoneInformation(&amp;TZI);<br>
  <br>
  int iStandardMonth = TZI.StandardDate.wMonth;<br>
  int iDaylightMonth = TZI.DaylightDate.wMonth;<br>
  <br>
  long nZoneCorrection = TZI.Bias;<br>
  <br>
  if( retCode == TIME_ZONE_ID_STANDARD){<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nZoneCorrection = nZoneCorrection +
  TZI.StandardBias;<br>
  }<br>
  else if( retCode == TIME_ZONE_ID_DAYLIGHT){<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nZoneCorrection = nZoneCorrection +
  TZI.DaylightBias;<br>
  }<br>
  else{<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ASSERT(0);<br>
  }<br>
  <br>
  nZoneCorrection = -nZoneCorrection;<br>
  int nTotalMinutes = tmUniversal.wHour * 60 +
  tmUniversal.wMinute + nZoneCorrection;<br>
  if(nTotalMinutes &lt; 0){<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nTotalMinutes+=24*60;<br>
  }<br>
  if(nTotalMinutes&gt;24*60){<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nTotalMinutes-=24*60;<br>
  }</font></p>
  <p><font size="2">tmLocal.wHour = nTotalMinutes /60;<br>
  tmLocal.wMinute = nTotalMinutes - tmLocal.wHour*60;<br>
  tmLocal.wSecond = tmUniversal.wSecond;</font></p>
</blockquote>
<p><font size="2">}</font></p>
<p><font size="2">/</font><font color="#008000" size="2">/
OnSyncro is called after ID_SYNCRO dialog button pressing.<br>
// It opens Internet connection, receives Universal Time,<br>
// calculates Local Time and set it in Windows.<br>
// Created by Alex.</font></p>
<p><font size="2">void CBSAtomicEduDlg::OnSyncro() <br>
{</font></p>
<blockquote>
  <p><font color="#008000" size="2">// Open Internet
  connection.</font><font size="2"><br>
  HINTERNET hInternet = ::InternetOpen(&quot;BSAtomicEdu&quot;,
  INTERNET_OPEN_TYPE_PRECONFIG , NULL, NULL, 0);<br>
  if(!hInternet){<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AfxMessageBox( &quot;Internet open error! Test your
  system and try again.&quot;, MB_OK | MB_ICONERROR );<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br>
  }</font></p>
  <p><font color="#008000" size="2">// Open site of U.S. Naval
  Observatory. </font><font size="2"><br>
  unsigned long Context = 777;<br>
  HINTERNET hHttp = ::InternetOpenUrl(hInternet,
  &quot;http://tycho.usno.navy.mil/cgi-bin/timer.pl&quot;,<br>
  NULL, -1L, INTERNET_FLAG_RELOAD, Context);</font></p>
  <p><font size="2">if(!hHttp){</font></p>
  <blockquote>
    <p><font size="2">AfxMessageBox(&quot;URL open
    error!&quot;, MB_OK | MB_ICONERROR );<br>
    </font></p>
    <p><font size="2">if(hInternet){<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InternetCloseHandle(hInternet);<br>
    } <br>
    return;</font></p>
  </blockquote>
  <p><font size="2">}</font></p>
  <p><font color="#008000" size="2">// Read the time from site</font><font
  size="2"><br>
  CString buff(' ',1024); <br>
  unsigned long NumberOfBytesRead = 0;<br>
  BOOL bRet = ::InternetReadFile(hHttp, (void
  *)((LPCTSTR)buff), 1024L, &amp;NumberOfBytesRead);</font></p>
  <p><font color="#008000" size="2">// Close Internet
  connection.</font><font size="2"><br>
  if(hHttp){<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InternetCloseHandle(hHttp);<br>
  }<br>
  if(hInternet){<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InternetCloseHandle(hInternet);<br>
  }</font></p>
  <p><font color="#008000" size="2">// Is received information
  correct?</font><font size="2"><br>
  if(!bRet){ <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AfxMessageBox( &quot;URL reading error! Test
  internet connection and try again.&quot;, MB_OK |
  MB_ICONERROR );<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br>
  }<br>
  if(NumberOfBytesRead != 603){<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AfxMessageBox( &quot;Unrecognized communication
  error!&quot;, MB_OK | MB_ICONERROR );<br>
  return;<br>
  }</font></p>
  <p><font size="2"><br>
  </font><font color="#008000" size="2">// Parse Universal time
  from string buffer to SYSTEMTIME struct.</font><font size="2"><br>
  SYSTEMTIME tmUniversal, tmLocal, dtOldTime;<br>
  ZeroMemory(&amp;tmUniversal,sizeof(tmUniversal));<br>
  GetLocalTime(&amp;tmLocal);<br>
  dtOldTime = tmLocal;</font></p>
  <p><font size="2">tmUniversal.wHour =
  atoi((LPCTSTR)buff.Mid(111,2));<br>
  tmUniversal.wMinute = atoi((LPCTSTR)buff.Mid(114,2));<br>
  tmUniversal.wSecond = atoi((LPCTSTR)buff.Mid(117,2));</font></p>
  <p><font color="#008000" size="2">// Calculate Local Time
  using received Universal Time.</font><font size="2"><br>
  LocalZoneTime(tmUniversal, tmLocal);</font></p>
  <p><font color="#008000" size="2">// Make Windows time
  correction.</font><font size="2"><br>
  SetLocalTime(&amp;tmLocal);</font></p>
  <p><font color="#008000" size="2">// Show report dialog box.</font><font
  size="2"><br>
  CString sReport;<br>
  sReport.Format( &quot;Successful synchronization!\n Time
  before: %02d:%02d:%02d.\n Time after:
  %02d:%02d:%02d.\n&quot;,<br>
  dtOldTime.wHour, dtOldTime.wMinute, dtOldTime.wSecond,
  tmLocal.wHour, tmLocal.wMinute, tmLocal.wSecond);</font></p>
  <p><font size="2">AfxMessageBox( sReport, MB_OK |
  MB_ICONINFORMATION );</font></p>
  <p><font size="2">return; </font></p>
</blockquote>
<p><font size="2">}</font></p>
</body>
</html>
Original Comments (3)
Recovered from Wayback Machine