Приветствую всех, лет наверное 10 назад мне попадались программы которые работали определенное время. Причем изменение время локально, никак не влияло на работу программы, время использования программы неизбежно уменьшалось. Все дело в том что программа связывалась с сервером, получала текущее время и сравнивало со временем установки. Ниже я приведу список сервером для синхронизации времени, а так же пример, позволяющий вам получить текущее время по МСК и дату с сервера. Все наши компьютеры при определенной настройке, аналогично производят синхронизацию времени и это позволяет нам видеть у себя точное локальное время. Компьютер его сам подводит если он не соответствует времени сервера.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using System.Net; using System.Net.Sockets; namespace ConsoleApp7 { class Program { static void Main(string[] args) { Console.WriteLine(GetNetworkTime()); Console.ReadKey(); } public static DateTime GetNetworkTime() { const string ntpServer = "pool.ntp.org"; // NTP message size - 16 bytes of the digest (RFC 2030) var ntpData = new byte[48]; //Setting the Leap Indicator, Version Number and Mode values ntpData[0] = 0x1B; //LI = 0 (no warning), VN = 3 (IPv4 only), Mode = 3 (Client Mode) var addresses = Dns.GetHostEntry(ntpServer).AddressList; //The UDP port number assigned to NTP is 123 var ipEndPoint = new IPEndPoint(addresses[0], 123); //NTP uses UDP using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) { socket.Connect(ipEndPoint); //Stops code hang if NTP is blocked socket.ReceiveTimeout = 3000; socket.Send(ntpData); socket.Receive(ntpData); } //Offset to get to the "Transmit Timestamp" field (time at which the reply //departed the server for the client, in 64-bit timestamp format." const byte serverReplyTime = 40; //Get the seconds part ulong intPart = BitConverter.ToUInt32(ntpData, serverReplyTime); //Get the seconds fraction ulong fractPart = BitConverter.ToUInt32(ntpData, serverReplyTime + 4); //Convert From big-endian to little-endian intPart = SwapEndianness(intPart); fractPart = SwapEndianness(fractPart); var milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L); //**UTC** time var networkDateTime = (new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc)).AddMilliseconds((long)milliseconds); return networkDateTime.ToLocalTime(); } // stackoverflow.com/a/3294698/162671 static uint SwapEndianness(ulong x) { return (uint)(((x & 0x000000ff) << 24) + ((x & 0x0000ff00) << 8) + ((x & 0x00ff0000) >> 8) + ((x & 0xff000000) >> 24)); } } } |
Есть и более короткая версия программы, основана на другом протоколе работы, однако сервер там забугорный и что бы получить время по МСК придется прибавить +3 часа.
Приведу список рабочих серверов синхронизации времени:
ntp1.stratum2.ru | |||||
ntp2.stratum2.ru | |||||
ntp3.stratum2.ru | |||||
ntp4.stratum2.ru | |||||
ntp5.stratum2.ru | |||||
ntp1.stratum1.ru | |||||
ntp2.stratum1.ru | |||||
ntp3.stratum1.ru | |||||
ntp4.stratum1.ru | |||||
ntp5.stratum1.ru |
1 2 3 4 5 6 7 8 |
static void Main(string[] args) { StreamReader rdr = new StreamReader(new TcpClient("time-a.timefreq.bldrdoc.gov", 13).GetStream()); Console.WriteLine(rdr.ReadToEnd()); Console.ReadKey(); } |
В попытках найти сервера с местным временем, у меня не увенчались успехом, однако отпарсить полученный результат так же не сложно.