Click here to Skip to main content
Licence CPOL
First Posted 24 May 2007
Views 23,142
Downloads 22
Bookmarked 18 times

Windows System Time Synchronizer

By | 24 May 2007 | Article
This utility synchronizes Windows system time with the Yahoo! server time using a web service

Screenshot - Article.gif

Introduction

This is a simple utility written in C# .NET Version 2.0. It synchronizes Windows system time with Yahoo! server time through a web service offered by Yahoo!.

Using the code

The utility makes an HTTP request to the Yahoo! URL, which returns Yahoo! server time as a timestamp in XML format. Then the XML is parsed to get the timestamp and is converted into regional date-time. Windows system time is modified to this using a P-Invoke function call.

/*
 * WINDOWS TIME SYNCHRONIZER - C# .NET
 * 
 * FILE NAME    :    Program.cs
 * 
 * DATE CREATED :    March 06, 2007, 12:05:54 PM
 * CREATED BY   :    Gunasekaran Paramesh
 * 
 * LAST UPDATED :    April 25, 2007, 12:38:12 PM
 * UPDATED BY   :    Gunasekaran Paramesh
 * 
 * DESCRIPTION  :    Synchronizes Windows System Time with Yahoo! Server Time.
*/

using System;
using System.Net;
using System.Xml;
using System.IO;
using System.Threading;
using System.Diagnostics;
using Microsoft.Win32;
using System.Configuration;
using System.Runtime.InteropServices;

namespace TryWinTimeSync
{
    class Program
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct SYSTEMTIME 
        {
            public short wYear;
            public short wMonth;
            public short wDayOfWeek;
            public short wDay;
            public short wHour;
            public short wMinute;
            public short wSecond;
            public short wMilliseconds;
        }

        [DllImport("kernel32.dll", SetLastError=true)]
        public static extern bool SetSystemTime( [In] ref SYSTEMTIME st );

        [STAThread]
        static void Main(string[] args)
        {
            BooleanSwitch Tracer = new BooleanSwitch("TraceSwitch", 
                "Trace for entire application");
            EventLog Log = null;

            try
            {
                // Initialize EventLog
                Log = new EventLog();
                if(!System.Diagnostics.EventLog.SourceExists("WinTimeSync"))
                    System.Diagnostics.EventLog.CreateEventSource(
                        "WinTimeSync", "Zion");
                Log.Source = "WinTimeSync";
                Log.Log = "Zion";
                
                if ( Tracer.Enabled )
                    Trace.Listeners.Add(new EventLogTraceListener(Log));

                Trace.WriteLineIf(Tracer.Enabled, "Starting WinTimeSync...");

                Boolean ServiceAlive = true;
                Double CurrentTimestamp = 0;

                Trace.WriteLineIf(Tracer.Enabled, 
                    "Opening configuration file for initializing" + 
                    " global settings...");

                Int32 SyncInterval = Convert.ToInt32(
                    ConfigurationSettings.AppSettings[
                    "SyncInterval"].ToString());
                String RequestURL = ConfigurationSettings.AppSettings[
                    "TimeServerURL"].ToString();

                Trace.WriteLineIf(Tracer.Enabled, 
                    "Global settings initialized [SyncInterval: " + 
                    SyncInterval + " minutes; RequestURL: " + 
                    RequestURL + "]");

                while ( ServiceAlive )
                {
                    Trace.WriteLineIf(!Tracer.Enabled, 
                    "Synchronizing system time with time server...");

                    // Send HTTP request for Timestamp
                    Trace.WriteLineIf(Tracer.Enabled, 
                        "Creating HTTP request to [" + RequestURL + "]");
                    WebRequest Req = WebRequest.Create(RequestURL);
                    Trace.WriteLineIf(Tracer.Enabled, 
                        "Setting default proxy for the HTTP request...");
                    Req.Proxy = WebProxy.GetDefaultProxy();
                    Trace.WriteLineIf(Tracer.Enabled, 
                        "Sending HTTP request...");
                    WebResponse Res = Req.GetResponse();

                    // Save as Timestamp as a temporary XML file
                    String TempFile = Guid.NewGuid().ToString() + ".xml";
                    Trace.WriteLineIf(Tracer.Enabled, 
                        "Creating a temporary XML file [" + TempFile + "]");
                    StreamWriter SW = new StreamWriter(TempFile);
                    Trace.WriteLineIf(Tracer.Enabled, 
                        "Saving HTTP response to the temporary XML file...");
                    SW.Write(new StreamReader(
                        Res.GetResponseStream()).ReadToEnd());
                    SW.Close();

                    // Read the XML file and get the Timestamp value
                    Trace.WriteLineIf(Tracer.Enabled, 
                        "Opening the temporary XML file...");
                    XmlTextReader MyXML = new XmlTextReader(TempFile);
                    Trace.WriteLineIf(Tracer.Enabled, 
                        "Reading the temporary XML file...");
                    while ( MyXML.Read() )
                    {
                        switch ( MyXML.NodeType )
                        {
                            case XmlNodeType.Element:
                            if ( MyXML.Name == "Timestamp" )
                            {
                                Trace.WriteLineIf(Tracer.Enabled, 
                                    "Retriving the current timestamp" + 
                                    " from the temporary XML file...");
                                CurrentTimestamp = Convert.ToDouble(
                                    MyXML.ReadInnerXml());
                                Trace.WriteLineIf(Tracer.Enabled, 
                                    "Current timestamp retrived [
                                    " + CurrentTimestamp + "]");
                            }
                            break;
                        }
                    }
                    Trace.WriteLineIf(Tracer.Enabled, 
                        "Closing the temporary XML file...");
                    MyXML.Close();

                    // Delete the temporary XML file
                    FileInfo TFile = new FileInfo(TempFile);
                    Trace.WriteLineIf(Tracer.Enabled, 
                        "Deleting the temporary XML file...");
                    TFile.Delete();

                    // Convert Timestamp to Time
                    DateTime MyDateTime = 
                        new DateTime(1970, 1, 1, 0, 0, 0, 0);
                    Trace.WriteLineIf(Tracer.Enabled, 
                        "Converting the timestamp to time...");
                    MyDateTime = MyDateTime.AddSeconds(CurrentTimestamp);
                    Trace.WriteLineIf(Tracer.Enabled, 
                        "Timestamp converted to time [
                        " + MyDateTime.ToLocalTime() + "]");

                    // Change the system time
                    SYSTEMTIME SysTime = new SYSTEMTIME();
                    SysTime.wYear = (short) MyDateTime.Year;
                    SysTime.wMonth = (short) MyDateTime.Month; 
                    SysTime.wDay = (short) MyDateTime.Day;
                    SysTime.wHour = (short) MyDateTime.Hour;
                    SysTime.wMinute = (short) MyDateTime.Minute;
                    SysTime.wSecond = (short) MyDateTime.Second;
                    Trace.WriteLineIf(Tracer.Enabled, 
                        "Setting the system time...");
                    SetSystemTime(ref SysTime);

                    Trace.WriteLineIf(Tracer.Enabled, 
                        "Switching to sleep state until SyncInterval...");
                    for ( int i = 0; i < SyncInterval; i++ )
                        Thread.Sleep(1000 * 60);
                        Trace.WriteLineIf(Tracer.Enabled, 
                            "Switching back to active mode...");
                }
            }
            catch ( Exception Ex )
            {
                // Log for errors                
                if ( Tracer.Enabled )
                    Log.WriteEntry(Ex.StackTrace, EventLogEntryType.Error);
                else
                    Log.WriteEntry(Ex.Message, EventLogEntryType.Error);
            }
        }
    }
}

Sample configuration file

Below is the sample configuration file. TraceSwitch is used to enable debug log messages. SyncInterval specifies the elapsed time in seconds where the utility synchronizes the Windows system time with the Yahoo! time server. TimeServerURL specifies the actual Yahoo! URL which, on request, returns the server time.

<configuration>
    <system.diagnostics>
        <switches>
            <add name="TraceSwitch" value="1" />
        </switches>
    </system.diagnostics>
    <appSettings>
        <add key="SyncInterval" value="60" />
        <add key="TimeServerURL" value=
"http://developer.yahooapis.com/TimeService/V1/getTime?appid=YahooDemo" />
    </appSettings>
</configuration>

History

  • Baseline v1.0 - April 25, 2007

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Paramesh Gunasekaran

Software Developer (Senior)
HCL Technologies
India India

Member

Paramesh Gunasekaran is currently working as a Software Engineer in HCL Technologies, India. He obtained his Bachelor's degree in Information Technology from Anna University, India. His research areas include Computational Biology, Artificial Neural Networks and Network Engineering. He has also received international acclaim for authoring industry papers in these areas. He is a Microsoft Certified Professional in ASP.NET/C# and has also been working in .NET technologies for more than 5 years.
 
Blog: http://sysref.blogspot.com
_

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralMy vote of 1 PinmemberDiptimoy123418:24 7 Dec '11  
GeneralNTP PinmemberWael Al Wirr3:21 9 Aug '07  
Generalit visits strange adds sites ?! Pinmemberandré_k21:02 17 Jul '07  
QuestionWhy this when there is NTP? PinmemberRamon Smits4:12 24 May '07  
AnswerRe: Why this when there is NTP? PinmemberGunasekaran Paramesh7:55 24 May '07  
GeneralRe: Why this when there is NTP? PinmemberRamon Smits11:41 24 May '07  
AnswerRe: Why this when there is NTP? Pinmembersillett14:40 24 May '07  
GeneralRe: Why this when there is NTP? PinmemberRamon Smits21:31 24 May '07  
GeneralRe: Why this when there is NTP? Pinmembersillett1:54 25 May '07  
AnswerRe: Why this when there is NTP? PinmemberRamon Smits2:02 25 May '07  
GeneralRe: Why this when there is NTP? PinmemberJLester3:11 29 May '07  
Not everything is as black and white as you would like to make it seem. Yes, computers in corporate environments should sync with domain controllers but this is not always possible.
 
Recently, I had to do something very similar to this, and the article here would have been an excellent reference for me. In my case the computer was not going to be added to the corporate domain, and because the ports were blocked NTP was unavailable.
 
I agree that a little statement mentioning NTP would have been useful but sitting on your moral programming high ground saying one should not use this method, and NTP is the only way it should be done, is just unrealistic and very short sighted.
 
Nice article, even if it did come 3 months to late for me :P

AnswerRe: Why this when there is NTP? PinmemberRamon Smits4:51 29 May '07  
GeneralRe: Why this when there is NTP? PinmemberJLester5:26 29 May '07  
AnswerRe: Why this when there is NTP? PinmemberAndyCLon22:21 28 May '07  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web04 | 2.5.120529.1 | Last Updated 24 May 2007
Article Copyright 2007 by Paramesh Gunasekaran
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid