一个安全可靠的NTP时间同步库,支持多服务器故障转移。
License
—
Deps
0
Install Size
—
Vulns
✓ 0
Published
Jun 20, 2025
$ dotnet add package NtpSecureSyncEnglish Version: README.en.md
一个安全、高性能的NTP客户端库,支持NTPv3和NTPv4协议。
dotnet add package NtpSecureSync
// 使用默认配置(系统本地时区)
var client = new NtpClient();
var networkTime = await client.GetNetworkTimeAsync();
// 使用特定服务器
var timeFromServer = await client.GetNetworkTimeAsync("pool.ntp.org");
// 使用多个服务器(故障转移)
var servers = new[] { "time.windows.com", "time.nist.gov", "pool.ntp.org" };
var timeWithFailover = await client.GetNetworkTimeAsync(servers);
// 1. 使用特定时区
var options = new NtpClientOptions
{
Version = NtpVersion.Version4,
EnableNetworkDelayCompensation = true,
TargetTimeZoneId = "China Standard Time" // 中国标准时间
};
var client = new NtpClient(options);
var timeInfo = await client.GetDetailedTimeAsync("pool.ntp.org");
Console.WriteLine($"北京时间: {timeInfo.ServerTime:yyyy-MM-dd HH:mm:ss.fff}");
Console.WriteLine($"时区: {timeInfo.TimeZone.DisplayName}");
// 2. 获取可用时区列表
foreach (var tz in TimeZoneInfo.GetSystemTimeZones())
{
Console.WriteLine($"ID: {tz.Id}, 显示名称: {tz.DisplayName}");
}
// 3. 常用时区ID
// - "China Standard Time" (中国标准时间)
// - "Eastern Standard Time" (美国东部时间)
// - "UTC" (协调世界时)
// - "Tokyo Standard Time" (东京标准时间)
// - "Pacific Standard Time" (太平洋标准时间)
var options = new NtpClientOptions
{
Version = NtpVersion.Version4,
EnableNetworkDelayCompensation = true,
Timeout = 5000,
RetryCount = 3,
EnableNts = true,
AutoDowngrade = true,
DefaultServers = new[]
{
"time.windows.com",
"time.nist.gov"
}
};
var client = new NtpClient(options);
var timeInfo = await client.GetDetailedTimeAsync("pool.ntp.org");
Console.WriteLine($"服务器时间: {timeInfo.ServerTime}");
Console.WriteLine($"本地时间: {timeInfo.LocalTime}");
Console.WriteLine($"时间偏移: {timeInfo.TimeOffset.TotalMilliseconds:F2}ms");
Console.WriteLine($"往返延迟: {timeInfo.RoundTripDelay.TotalMilliseconds:F2}ms");
Console.WriteLine($"估计误差: {timeInfo.EstimatedError:F2}ms");
Console.WriteLine($"服务器层次: {timeInfo.Stratum}");
Console.WriteLine($"时区: {timeInfo.TimeZone.DisplayName}");
public class TimeService
{
private readonly INtpClient _ntpClient;
private NtpTimeInfo _lastTimeInfo;
private readonly object _lock = new object();
private readonly double _maxErrorThreshold; // 最大可接受误差(毫秒)
public TimeService(INtpClient ntpClient, double maxErrorThreshold = 10000)
{
_ntpClient = ntpClient;
_maxErrorThreshold = maxErrorThreshold;
}
public async Task<DateTime> GetCurrentTimeAsync()
{
try
{
// 尝试从NTP服务器获取时间
var timeInfo = await _ntpClient.GetDetailedTimeAsync("pool.ntp.org");
lock (_lock)
{
_lastTimeInfo = timeInfo;
}
return timeInfo.ServerTime;
}
catch (Exception)
{
// 如果网络不可用,使用缓存的时间信息
lock (_lock)
{
if (_lastTimeInfo != null)
{
var elapsed = DateTime.UtcNow - _lastTimeInfo.LastSyncTime;
var estimatedError = _lastTimeInfo.EstimatedError + elapsed.TotalMilliseconds;
if (estimatedError > _maxErrorThreshold)
{
throw new NtpException("缓存时间误差超过阈值");
}
// 使用缓存的时区信息
return TimeZoneInfo.ConvertTime(
DateTime.UtcNow.Add(_lastTimeInfo.TimeOffset),
TimeZoneInfo.Utc,
_lastTimeInfo.TimeZone
);
}
}
throw;
}
}
}
public class AdvancedTimeService
{
private readonly INtpClient _ntpClient;
private readonly string[] _servers;
private NtpTimeInfo _lastTimeInfo;
private readonly object _lock = new object();
private readonly Timer _syncTimer;
private readonly ILogger _logger;
private readonly TimeSpan _syncInterval;
private readonly double _maxErrorThreshold;
public AdvancedTimeService(
INtpClient ntpClient,
ILogger logger,
TimeSpan? syncInterval = null,
double maxErrorThreshold = 10000,
params string[] servers)
{
_ntpClient = ntpClient;
_logger = logger;
_servers = servers.Length > 0 ? servers : new[] { "pool.ntp.org" };
_syncInterval = syncInterval ?? TimeSpan.FromHours(1);
_maxErrorThreshold = maxErrorThreshold;
// 创建定时同步任务
_syncTimer = new Timer(SyncTime, null, TimeSpan.Zero, _syncInterval);
}
private async void SyncTime(object? state)
{
try
{
foreach (var server in _servers)
{
try
{
var timeInfo = await _ntpClient.GetDetailedTimeAsync(server);
lock (_lock)
{
_lastTimeInfo = timeInfo;
}
_logger.LogInformation(
"时间同步成功。服务器:{Server}, 偏移:{Offset}ms, 误差:{Error}ms",
server,
timeInfo.TimeOffset.TotalMilliseconds,
timeInfo.EstimatedError);
return;
}
catch (Exception ex)
{
_logger.LogWarning(ex, "服务器{Server}同步失败", server);
}
}
}
catch (Exception ex)
{
_logger.LogError(ex, "时间同步失败");
}
}
public DateTime GetCurrentTime()
{
lock (_lock)
{
if (_lastTimeInfo == null)
{
throw new InvalidOperationException("尚未完成首次时间同步");
}
var elapsed = DateTime.UtcNow - _lastTimeInfo.LastSyncTime;
var estimatedError = _lastTimeInfo.EstimatedError + elapsed.TotalMilliseconds;
if (estimatedError > _maxErrorThreshold)
{
_logger.LogWarning(
"时间误差({Error}ms)超过阈值({Threshold}ms)",
estimatedError,
_maxErrorThreshold);
}
return DateTime.Now.Add(_lastTimeInfo.TimeOffset);
}
}
public void Dispose()
{
_syncTimer?.Dispose();
}
}
同步频率
误差控制
故障处理
性能优化
安全考虑
MIT