NTP Query
using System;using System.Diagnostics;using System.Net;using System.Net.Sockets;using System.Threading.Tasks; namespace CheckTimeServer.Console{ public static class Program { public static async Task Main(string[] args) { // // Example usage: // var networkTime = await GetNetworkTime(); if (networkTime.HasValue) { var localZone = TimeZoneInfo.Local; System.Console.WriteLine("Network time: {0} ({1})", networkTime.Value, localZone.IsDaylightSavingTime(networkTime.Value) ? localZone.DaylightName : localZone.StandardName); } else { System.Console.WriteLine("Could not retrieve network time."); } System.Console.ReadKey(); } private static async Task<DateTime?> GetNetworkTime(string ntpServer = "pool.ntp.org") { // https://stackoverflow.com/questions/1193955/how-to-query-an-ntp-server-using-c if (ntpServer == null) { throw new ArgumentNullException(nameof(ntpServer)); } try { const int daysTo1900 = 1900 * 365 + 95; // 95 = offset for leap-years etc. const long ticksPerSecond = 10000000L; const long ticksPerDay = 24 * 60 * 60 * ticksPerSecond; const long ticksTo1900 = daysTo1900 * ticksPerDay; var ntpData = new byte[48]; ntpData[0] = 0x1B; // LeapIndicator = 0 (no warning), VersionNum = 3 (IPv4 only), Mode = 3 (Client Mode) var addresses = Dns.GetHostEntry(ntpServer).AddressList; var ipEndPoint = new IPEndPoint(addresses[0], 123); // ReSharper disable once RedundantAssignment var pingDuration = Stopwatch.GetTimestamp(); // temp access (JIT-Compiler need some time at first call) using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) { await socket.ConnectAsync(ipEndPoint); socket.ReceiveTimeout = 5000; socket.Send(ntpData); pingDuration = Stopwatch.GetTimestamp(); // after Send-Method to reduce WinSocket API-Call time socket.Receive(ntpData); pingDuration = Stopwatch.GetTimestamp() - pingDuration; } var pingTicks = pingDuration * ticksPerSecond / Stopwatch.Frequency; // optional: display response-time // Console.WriteLine("{0:N2} ms", new TimeSpan(pingTicks).TotalMilliseconds); var intPart = (long) ntpData[40] << 24 | (long) ntpData[41] << 16 | (long) ntpData[42] << 8 | ntpData[43]; var fractPart = (long) ntpData[44] << 24 | (long) ntpData[45] << 16 | (long) ntpData[46] << 8 | ntpData[47]; var netTicks = intPart * ticksPerSecond + (fractPart * ticksPerSecond >> 32); var networkDateTime = new DateTime(ticksTo1900 + netTicks + pingTicks / 2); return networkDateTime.ToLocalTime(); // without ToLocalTime() = faster } catch { // fail return null; } } }}