HS Banner
Back
Get DateTime from NTP Server

Author: Admin 07/15/2026
Language: C#
Tags: ntp datetime udp


Description:

Here's some code I used in a time clock app to get the DateTime from an NTP source.

Article:

/// <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);
    }
}



Back
Comments
Add Comment
There are no comments yet.