Author: Admin 07/15/2026
Language:
C#
Tags: ntp datetime udp
Here's some code I used in a time clock app to get the DateTime from an NTP source.
/// <summary>
/// Retrieves the current UTC time from an NTP server.
/// </summary>
/// <param name="ntpServer">The hostname of the NTP server.</param>
/// <returns>UTC DateTime from the NTP server.</returns>
public static DateTime GetNetworkTime(string ntpServer = "0.us.pool.ntp.org")
{
const int ntpPort = 123;
byte[] ntpData = new byte[48];
// Set protocol version and mode (client mode)
ntpData[0] = 0x1B; // LI = 0, VN = 3, Mode = 3
try
{
IPAddress[] addresses = Dns.GetHostAddresses(ntpServer);
if (addresses.Length == 0)
throw new Exception("No IP addresses found for NTP server.");
IPEndPoint endPoint = new IPEndPoint(addresses[0], ntpPort);
using (UdpClient udpClient = new UdpClient())
{
udpClient.Client.ReceiveTimeout = 3000; // 3 seconds timeout
udpClient.Send(ntpData, ntpData.Length, endPoint);
IPEndPoint remoteEndPoint = endPoint;
byte[] response = udpClient.Receive(ref remoteEndPoint);
if (response.Length < 48)
throw new Exception("Invalid NTP response length.");
// Extract the transmit timestamp (bytes 40-47)
ulong intPart = BitConverter.ToUInt32(response, 40);
ulong fracPart = BitConverter.ToUInt32(response, 44);
// Convert from big-endian to little-endian
intPart = SwapEndianness(intPart);
fracPart = SwapEndianness(fracPart);
// NTP time starts on 1900-01-01
const ulong ticksPerSecond = 10000000UL;
const ulong ticksPerDay = ticksPerSecond * 60 * 60 * 24;
DateTime ntpEpoch = new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc);
ulong seconds = intPart;
ulong fraction = fracPart;
double totalSeconds = seconds + (fraction / (double)uint.MaxValue);
DateTime networkDateTime = ntpEpoch.AddSeconds(totalSeconds);
return networkDateTime;
}
}
catch (SocketException ex)
{
throw new Exception("Network error while contacting NTP server: " + ex.Message, ex);
}
catch (Exception ex)
{
throw new Exception("Error retrieving NTP time: " + ex.Message, ex);
}
}
/// <summary>
/// Swap endianness of a 32-bit unsigned integer.
/// </summary>
private static uint SwapEndianness(ulong x)
{
return (uint)(((x & 0x000000ff) << 24) +
((x & 0x0000ff00) << 8) +
((x & 0x00ff0000) >> 8) +
((x & 0xff000000) >> 24));
}Usage:
private void lbNtpTime_Loaded(object sender, RoutedEventArgs e)
{
try
{
DateTime ntpTime = GetNetworkTime();
lbNtpTime.Content = "NTP UTC Time: " + ntpTime.ToString("yyyy-MM-dd HH:mm:ss") + " UTC";
lbNtpTime2.Content = "Local Time: " + ntpTime.ToLocalTime().ToString("yyyy/MM/dd HH:mm:ss");
}
catch (Exception ex)
{
MessageBox.Show("Failed to get NTP time: " + ex.Message);
}
}