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" />
                    
Directory.Packages.props
<PackageReference Include="NtpSecureSync" />
                    
Project file
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
                    
#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
                    
Install as a Cake Addin
#tool nuget:?package=NtpSecureSync&version=1.4.6
                    
Install as a Cake Tool

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();
    }
}

缓存策略建议

  1. 同步频率

    • 高精度要求:每5-15分钟同步一次
    • 一般精度要求:每1-4小时同步一次
    • 低精度要求:每12-24小时同步一次
  2. 误差控制

    • 关键系统:最大误差限制在100ms以内
    • 一般应用:最大误差限制在1-10秒
    • 非关键系统:可接受更大误差
  3. 故障处理

    • 实现优雅降级
    • 使用多个NTP服务器
    • 记录同步失败的原因
    • 监控时间偏移趋势
  4. 性能优化

    • 使用内存缓存
    • 实现异步预加载
    • 避免频繁同步
    • 使用后台任务同步
  5. 安全考虑

    • 验证时间偏移的合理性
    • 防止时间回跳
    • 记录异常时间变化
    • 考虑使用NTS(如果可用)

许可证

MIT

Product 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.

Version Downloads Last Updated
1.4.6 197 6/20/2025
1.3.16 198 5/28/2025
1.3.15 203 5/28/2025