NtpSecureSync 1.4.6
dotnet add package NtpSecureSync --version 1.4.6
NuGet\Install-Package NtpSecureSync -Version 1.4.6
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="NtpSecureSync" Version="1.4.6" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="NtpSecureSync" Version="1.4.6" />
<PackageReference Include="NtpSecureSync" />
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add NtpSecureSync --version 1.4.6
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: NtpSecureSync, 1.4.6"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package NtpSecureSync@1.4.6
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=NtpSecureSync&version=1.4.6
#tool nuget:?package=NtpSecureSync&version=1.4.6
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
NtpSecureSync
English Version: README.en.md
一个安全、高性能的NTP客户端库,支持NTPv3和NTPv4协议。
特性
- 支持NTPv3和NTPv4协议
- 支持多服务器故障转移
- 支持网络延迟补偿
- 支持全球时区
- 提供详细的时间同步信息
- 支持时间误差估算
- 支持NTS(计划中)
安装
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();
}
}
缓存策略建议
同步频率
- 高精度要求:每5-15分钟同步一次
- 一般精度要求:每1-4小时同步一次
- 低精度要求:每12-24小时同步一次
误差控制
- 关键系统:最大误差限制在100ms以内
- 一般应用:最大误差限制在1-10秒
- 非关键系统:可接受更大误差
故障处理
- 实现优雅降级
- 使用多个NTP服务器
- 记录同步失败的原因
- 监控时间偏移趋势
性能优化
- 使用内存缓存
- 实现异步预加载
- 避免频繁同步
- 使用后台任务同步
安全考虑
- 验证时间偏移的合理性
- 防止时间回跳
- 记录异常时间变化
- 考虑使用NTS(如果可用)
许可证
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
net8.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.