import 'package:nomo/app/data/sp/ix_sp.dart'; import 'package:ntp/ntp.dart'; import 'package:system_clock/system_clock.dart'; import 'log/logger.dart'; class NtpTimeService { static const String TAG = 'NtpTimeService'; static final NtpTimeService _instance = NtpTimeService._internal(); factory NtpTimeService() => _instance; NtpTimeService._internal(); // 国内外NTP服务器列表 static const List _ntpServers = [ // 国内服务器 'time.cloudflare.com', 'pool.ntp.org', 'time.google.com', 'time.nist.gov', 'ntp.aliyun.com', 'ntp1.aliyun.com', 'ntp2.aliyun.com', 'ntp.tencent.com', 'time1.cloud.tencent.com', 'time2.cloud.tencent.com', 'time3.cloud.tencent.com', 'ntp.ntsc.ac.cn', 'cn.pool.ntp.org', 'time.windows.com', 'time.apple.com', 'time-a-g.nist.gov', 'time-b-g.nist.gov', 'time-c-g.nist.gov', 'time-d-g.nist.gov', 'time-e-g.nist.gov', 'time-a-wwv.nist.gov', 'time-b-wwv.nist.gov', 'time-c-wwv.nist.gov', 'time-d-wwv.nist.gov', 'time-e-wwv.nist.gov', 'time-a-b.nist.gov', 'time-b-b.nist.gov', 'time-c-b.nist.gov', 'time-d-b.nist.gov', 'time-e-b.nist.gov', ]; DateTime? _ntpInitialTime; Duration? _elapsedRealtimeInitial; String? _currentServer; bool get isInitialized => _ntpInitialTime != null && _elapsedRealtimeInitial != null; String? get currentServer => _currentServer; /// 初始化:从多个NTP服务器获取时间,并记录系统启动时间 Future initialize() async { try { log(TAG, 'NTP time calibrator initialization begins...'); // 尝试多个NTP服务器 for (final server in _ntpServers) { try { log(TAG, 'Try to connect to the NTP server: $server'); // 加上请求的时间 final requestTime = DateTime.now(); _ntpInitialTime = await NTP.now(lookUpAddress: server); final responseTime = DateTime.now(); final requestDuration = responseTime.difference(requestTime); log(TAG, 'Request time: ${requestTime.toIso8601String()}'); log(TAG, 'Response time: ${responseTime.toIso8601String()}'); log( TAG, 'Request time-consuming: ${requestDuration.inMilliseconds}ms', ); _ntpInitialTime = _ntpInitialTime?.add(requestDuration); _elapsedRealtimeInitial = SystemClock.elapsedRealtime(); _currentServer = server; log(TAG, 'NTP time calibration is successful, server: $server'); log(TAG, 'Initial time of NTP: $_ntpInitialTime'); log(TAG, 'System start-up time: $_elapsedRealtimeInitial'); log(TAG, 'Current time: ${DateTime.now().toIso8601String()}'); return true; } catch (e) { log(TAG, 'NTP server $server connection failed: $e'); continue; } } log(TAG, 'All NTP server connection failed, using system time'); return false; } catch (e) { log(TAG, 'NTP time calibrator initialization abnormality: $e'); return false; } } /// 获取当前"网络时间",通过系统运行时间 + NTP 差值计算 DateTime getCurrentTime() { if (!isInitialized) { final appConfig = IXSP.getAppConfig(); if (appConfig != null && appConfig.serverTime != null) { return DateTime.fromMillisecondsSinceEpoch(appConfig.serverTime!); } return DateTime.now(); } final currentElapsedRealtime = SystemClock.elapsedRealtime(); final elapsed = currentElapsedRealtime - _elapsedRealtimeInitial!; return _ntpInitialTime!.add(elapsed); } /// 获取当前时间戳(毫秒) int getCurrentTimestamp() { final currentTime = getCurrentTime(); return currentTime.millisecondsSinceEpoch; } int getNtpInitialTime() { if (!isInitialized) { return getCurrentTimestamp(); } return _ntpInitialTime?.millisecondsSinceEpoch ?? getCurrentTimestamp(); } int getElapsedRealtimeInitial() { if (!isInitialized) { return SystemClock.elapsedRealtime().inMilliseconds; } return _elapsedRealtimeInitial?.inMilliseconds ?? SystemClock.elapsedRealtime().inMilliseconds; } /// 同步一次 NTP,重新校准 Future resync() async { try { if (isInitialized) { return true; } log(TAG, 'Start resynchronizing NTP time...'); return await initialize(); } catch (e) { log(TAG, 'Resynchronization of NTP time failed: $e'); return false; } } }