64 lines
2.2 KiB
C#
64 lines
2.2 KiB
C#
using System;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
|
|
public class NtpService
|
|
{
|
|
private readonly string _ntpServer;
|
|
private TimeSpan _timeOffset = TimeSpan.Zero;
|
|
private DateTime _lastSync = DateTime.MinValue;
|
|
|
|
public NtpService(string ntpServer)
|
|
{
|
|
_ntpServer = ntpServer;
|
|
}
|
|
|
|
public DateTime GetCurrentTime()
|
|
{
|
|
// Sync with your NTP server every 1 hour
|
|
if ((DateTime.UtcNow - _lastSync).TotalHours > 1)
|
|
{
|
|
SyncWithNtp();
|
|
}
|
|
|
|
// Apply the offset so the clock advances smoothly between syncs
|
|
return DateTime.Now.Add(_timeOffset);
|
|
}
|
|
|
|
private void SyncWithNtp()
|
|
{
|
|
try
|
|
{
|
|
var ntpData = new byte[48];
|
|
ntpData[0] = 0x1B; // NTP request header (Client mode, Version 3)
|
|
|
|
var addresses = Dns.GetHostEntry(_ntpServer).AddressList;
|
|
var ipEndPoint = new IPEndPoint(addresses[0], 123);
|
|
|
|
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
|
|
{
|
|
socket.ReceiveTimeout = 3000;
|
|
socket.Connect(ipEndPoint);
|
|
socket.Send(ntpData);
|
|
socket.Receive(ntpData);
|
|
}
|
|
|
|
// Parse the 64-bit timestamp from the NTP response
|
|
ulong intPart = (ulong)ntpData[40] << 24 | (ulong)ntpData[41] << 16 | (ulong)ntpData[42] << 8 | (ulong)ntpData[43];
|
|
ulong fractPart = (ulong)ntpData[44] << 24 | (ulong)ntpData[45] << 16 | (ulong)ntpData[46] << 8 | (ulong)ntpData[47];
|
|
|
|
var milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L);
|
|
var networkTime = new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds((long)milliseconds);
|
|
|
|
// Calculate the difference between Pi's local UTC and NTP UTC
|
|
_timeOffset = networkTime - DateTime.UtcNow;
|
|
_lastSync = DateTime.UtcNow;
|
|
|
|
Console.WriteLine($"NTP Sync to {_ntpServer} successful. Offset: {_timeOffset.TotalMilliseconds:F1}ms");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"NTP Sync failed: {ex.Message}");
|
|
}
|
|
}
|
|
} |