using System; using UnityEngine; using System.Collections; /// /// 北京时间管理器 - 获取一次后持续自增 /// public class BeijingTimeManager : MonoSingleton { [Header("时间状态")] [SerializeField] private bool _isTimeSynced = false; // 是否已同步 [SerializeField] private DateTime _currentBeijingTime; // 当前北京时间 [SerializeField] private float _timeSinceLastSync; // 距离上次同步的秒数 // 公开属性供其他脚本访问 public DateTime CurrentBeijingTime { get { if (_isTimeSynced) { // 基准时间 + 流逝的时间 return _currentBeijingTime.AddSeconds(_timeSinceLastSync); } else { Debug.LogWarning("时间尚未同步,返回本地时间"); return DateTime.Now.AddHours(8); // 降级为本地时间+8小时 } } } public bool IsTimeSynced => _isTimeSynced; // 事件:当时间成功同步时触发 public event Action OnTimeSynced; private void Start() { SyncBeijingTime(); } private void Update() { if (_isTimeSynced) { // 持续累计时间 _timeSinceLastSync += Time.deltaTime; // 可选:每隔一段时间(如5分钟)自动校准 if (_timeSinceLastSync > 300f) // 5分钟 { StartCoroutine(AutoCalibrateTime()); } } } /// /// 手动触发时间同步 /// public void SyncBeijingTime() { StartCoroutine(FetchBeijingTime()); } /// /// 获取北京时间(协程) /// private IEnumerator FetchBeijingTime() { string[] timeServers = new string[] { "http://www.beijing-time.org/time.asp", "https://www.baidu.com", "https://www.taobao.com", }; DateTime beijingTime = DateTime.MinValue; bool success = false; foreach (string url in timeServers) { using (UnityEngine.Networking.UnityWebRequest request = UnityEngine.Networking.UnityWebRequest.Get(url)) { yield return request.SendWebRequest(); if (request.result == UnityEngine.Networking.UnityWebRequest.Result.Success) { string dateHeader = request.GetResponseHeader("Date"); if (!string.IsNullOrEmpty(dateHeader)) { try { // 解析GMT时间 DateTime gmtTime = DateTime.ParseExact(dateHeader, "ddd, dd MMM yyyy HH:mm:ss 'GMT'", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AssumeUniversal); beijingTime = gmtTime.AddHours(8); // 更新基准时间和计时器 _currentBeijingTime = beijingTime; _timeSinceLastSync = 0f; _isTimeSynced = true; Debug.Log($"时间同步成功!北京时间:{beijingTime:yyyy-MM-dd HH:mm:ss}"); // 触发事件 OnTimeSynced?.Invoke(beijingTime); success = true; break; } catch (Exception e) { Debug.LogWarning($"解析失败:{e.Message}"); continue; } } } } } if (!success) { Debug.LogError("所有时间服务器都失败了,使用本地时间作为备用"); _currentBeijingTime = DateTime.Now.AddHours(8); _timeSinceLastSync = 0f; _isTimeSynced = false; // 标记为未同步 } } /// /// 自动校准(后台静默同步) /// private IEnumerator AutoCalibrateTime() { Debug.Log("开始自动校准时间..."); // 保存当前累计时间,用于计算校准时的差距 float oldElapsed = _timeSinceLastSync; yield return StartCoroutine(FetchBeijingTime()); // 校准后可以计算误差 Debug.Log($"时间校准完成,误差:{_timeSinceLastSync - oldElapsed:F2}秒"); } }