SNTP/NTP Tutorial

Applies to: Rebex Total Pack, Rebex Time

Namespaces and assemblies 

SNTP (Simple Network Time Protocol) described in RFC 2030 is used to synchronize computer clocks in the Internet over UDP. For a list of publicly available NTP servers, check out ntp.isc.org website.

Alternatives to the SNTP protocol are Daytime (described in RFC 867) and Time protocols (described in RFC 868), which are lightweight protocols for synchronization of computer clock on network. They are not as accurate as SNTP, but they can also be used with TCP/IP (in addition to UDP). It is recommended to use SNTP to synchronize workstations. Still, if it is not possible to use UDP, Time and Daytime can be used.

To use the features of Rebex Time for .NET described here, reference the Rebex.Time.dll and Rebex.Common.dll assemblies from your project. It contains the Ntp, Time, Daytime and other classes in Rebex.Net namespace.

In your source files, import the following namespace:

using Rebex.Net;
Imports Rebex.Net

Synchronizing local time with time server 

Synchronizing the local time with a time server is a single line operation. Just use the static SynchronizeSystemClock method of the appropriate class.

// synchronize over NTP protocol
Ntp.SynchronizeSystemClock("test.rebex.net");

// synchronize over Time protocol
Time.SynchronizeSystemClock("test.rebex.net");

// synchronize over Daytime protocol
Daytime.SynchronizeSystemClock("test.rebex.net");
' synchronize over NTP protocol
Ntp.SynchronizeSystemClock("test.rebex.net")

' synchronize over Time protocol
Time.SynchronizeSystemClock("test.rebex.net")

' synchronize over Daytime protocol
Daytime.SynchronizeSystemClock("test.rebex.net")

If you need to specify some properties such as SNTP protocol version or maximum timeout, a slightly different code is required:

// initialize the Ntp object
Ntp ntp = new Ntp("test.rebex.net");

// set timeout to 5 seconds
ntp.Timeout = 5000;

// set the desired NTP version
ntp.VersionNumber = 4;

// sync local clock
ntp.SynchronizeSystemClock();
' initialize the Ntp object
Dim ntp As New Ntp("test.rebex.net")

' set timeout to 5 seconds
ntp.Timeout = 5000

' set the desired NTP version
ntp.VersionNumber = 4

' sync local clock
ntp.SynchronizeSystemClock()

Determining the time difference between the local time and a time server 

To obtain more info from a NTP server, create a Ntp instance and call the GetTime method. The returned NtpResponse contains the TimeOffset property which contains the time difference between the local computer and a remote time server.

// initialize the Ntp object
Ntp ntp = new Ntp("test.rebex.net");

// get server time
NtpResponse response = ntp.GetTime();

// get time difference
Console.WriteLine("Time difference is {0}", response.TimeOffset);
' initialize the Ntp object
Dim ntp As New Ntp("test.rebex.net")

' get server time
Dim response As NtpResponse = ntp.GetTime()

' get time difference
Console.WriteLine("Time difference is {0}", response.TimeOffset)

Retrieving more NTP server details 

You might also want to know whether the time server is Stratum 1 (primary and intended for synchronization between time servers) or Stratum 2 (for general use) or determine the supported protocol version. This and other info is available through the NtpPacket class, which is accessible as a Packet property of the NtpResponse:

// initialize the Ntp object
Ntp ntp = new Ntp("test.rebex.net");

// since we want to know the highest version the server supports, we
// must announce the highest ourselves (otherwise the server would use
// the compatibility mode)
ntp.VersionNumber = 4;

// get info from the NTP server
NtpResponse response = ntp.GetTime();
NtpPacket packet = response.Packet;

// server stratum and NTP version
Console.WriteLine("Server has stratum {0} and runs NTP version {1}.",
packet.Stratum,
packet.VersionNumber);

// processing time
Console.WriteLine("It received our request at {0} UTC and responded to it at {1} UTC.",
packet.ReceiveTimestamp,
packet.TransmitTimestamp);

// desired time
Console.WriteLine("Local time is {0} and should be adjusted by {1}",
DateTime.Now,
response.TimeOffset.ToTimeSpan());
' initialize the Ntp object
Dim ntp As New Ntp("test.rebex.net")

' since we want to know the highest version the server supports, we
' must announce the highest ourselves (otherwise the server would use
' the compatibility mode)
ntp.VersionNumber = 4

' get info from NTP server
Dim response As NtpResponse = ntp.GetTime()
Dim packet As NtpPacket = response.Packet

' server stratum and NTP version
Console.WriteLine("Server has stratum {0} and runs NTP version {1}.", packet.Stratum, packet.VersionNumber)

' processing time
Console.WriteLine("It received our request at {0} UTC and responded to it at {1} UTC.", packet.ReceiveTimestamp, packet.TransmitTimestamp)

' desired time
Console.WriteLine("Local time is {0} and should be adjusted by {1}", DateTime.Now, response.TimeOffset.ToTimeSpan())

Converting between NTP and .NET time formats 

SNTP uses its own time format with different precision than .NET Framework. Rebex Time library encapsulates this information in NtpTimestamp and NtpTimestampDifference value types. The NtpTimestamp contains the time as received from a NTP server and NtpTimestampDifference contains a difference between two timestamps.

The following table shows the most commonly-used methods and properties of the classes mentioned above.

NtpTimestamp properties and conversion methods
Property/Method Description
byte[] ToArray() 8 bytes of raw data as received from the server.
DateTime ToLocalTime() The time represented as .NET's DateTime and adjusted to the local time zone.
DateTime ToUniversalTime() The time represented as .NET's DateTime in UTC.
int ToUnixTime() The number of seconds since the beginning of the Unix epoch (January 1st, 1970).
int Microseconds The sub-second part of the time difference, on microsecond scale. A number between 0 and 10^6-1.

 

TimestampDifference properties and conversion methods
Property/Method Description
TimeSpan ToTimeSpan() Converts the difference to .NET's TimeSpan.
int Microseconds The sub-second part of the time difference, on microsecond scale. A number between -10^6+1 and 10^6-1.
double TotalSeconds The value of this instance expressed in whole and fractional seconds.

Changing the local system time 

Rebex Time now includes the Rebex.SystemClock class that enables you to change the local computer clock. The SetClock method sets the local clock the specified time value.

// display the original local time
Console.WriteLine("Current time is {0}", DateTime.Now);

// change the current time to the end of Maya calendar
// to see what the end of mankind looks like...
SystemClock.SetClock(new DateTime(2012, 12, 21));
Console.WriteLine("Current time is {0}", DateTime.Now);
' display the original local time
Console.WriteLine("Current time is {0}", DateTime.Now)

' change the current time to the end of Maya calendar
' to see what the end of mankind looks like...
SystemClock.SetClock(New DateTime(2012, 12, 21))
Console.WriteLine("Current time is {0}", DateTime.Now)

The AdjustClock moves the local clock by the specified NtpTimestampDifference value, for example by the TimeOffset received from an NTP server.

// get the time difference
NtpTimestampDifference difference = new Ntp("test.rebex.net").GetTime().TimeOffset;

// adjust the time by the difference
SystemClock.AdjustClock(difference);
' get the time difference
Dim difference As NtpTimestampDifference = New Ntp("test.rebex.net").GetTime().TimeOffset

' adjust the time by the difference
SystemClock.AdjustClock(difference)

Back to tutorial list...