using System; using UnityEngine; using System.Collections; using UnityEngine.Networking; using Newtonsoft.Json.Linq; /// /// 北京时间管理器 - 获取一次后持续自增 /// 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); } return DateTime.Now; // 未同步时返回本地时间 } } /// /// 获取时间戳(秒)- 1970-01-01 08:00:00 到现在的秒数 /// public long CurrentTimestamp { get { DateTime beijingTime = CurrentBeijingTime; DateTime epoch = new DateTime(1970, 1, 1, 8, 0, 0); // 北京时间起点 return (long)(beijingTime - epoch).TotalSeconds; } } /// /// 获取时间戳(毫秒) /// public long CurrentTimestampMs { get { DateTime beijingTime = CurrentBeijingTime; DateTime epoch = new DateTime(1970, 1, 1, 8, 0, 0); // 北京时间起点 return (long)(beijingTime - epoch).TotalMilliseconds; } } public bool IsTimeSynced => _isTimeSynced; public event Action OnTimeSynced; private void Start() { SyncBeijingTime(); } private void Update() { if (_isTimeSynced) { _timeSinceLastSync += Time.deltaTime; } } /// /// 同步北京时间 /// public void SyncBeijingTime() { StartCoroutine(FetchBeijingTime()); } private IEnumerator FetchBeijingTime() { string[] timeServers = new string[] { "https://timeapi.io/api/Time/current/zone?timeZone=Asia/Shanghai", "http://worldtimeapi.org/api/timezone/Asia/Shanghai", "https://quan.suning.com/getSysTime.do" }; foreach (string url in timeServers) { using (UnityWebRequest request = UnityWebRequest.Get(url + "?_=" + DateTime.Now.Ticks)) { request.timeout = 5; yield return request.SendWebRequest(); if (request.result == UnityWebRequest.Result.Success) { string jsonText = request.downloadHandler.text; Debug.Log($"返回原始数据:{jsonText}"); if (!jsonText.TrimStart().StartsWith("{")) { Debug.LogWarning("返回的不是 JSON,跳过该源"); continue; } try { JObject json = JObject.Parse(jsonText); if (url.Contains("timeapi.io")) { string timeStr = json["dateTime"]?.ToString(); Debug.Log(timeStr); if (!string.IsNullOrEmpty(timeStr)) { _currentBeijingTime = DateTime.Parse(timeStr); _timeSinceLastSync = 0; _isTimeSynced = true; Debug.Log($"北京时间同步成功:{_currentBeijingTime:yyyy-MM-dd HH:mm:ss}"); OnTimeSynced?.Invoke(_currentBeijingTime); yield break; } } else if (url.Contains("worldtimeapi")) { string timeStr = json["datetime"]?.ToString(); Debug.Log(timeStr); if (!string.IsNullOrEmpty(timeStr)) { _currentBeijingTime = DateTimeOffset.Parse(timeStr) .ToOffset(TimeSpan.FromHours(8)) .DateTime; _timeSinceLastSync = 0; _isTimeSynced = true; Debug.Log($"北京时间同步成功:{_currentBeijingTime:yyyy-MM-dd HH:mm:ss}"); OnTimeSynced?.Invoke(_currentBeijingTime); yield break; } } else if (url.Contains("suning")) { string timeStr = json["sysTime2"]?.ToString(); Debug.Log(timeStr); if (!string.IsNullOrEmpty(timeStr)) { _currentBeijingTime = DateTime.ParseExact(timeStr, "yyyy-MM-dd HH:mm:ss", null); _timeSinceLastSync = 0; _isTimeSynced = true; Debug.Log($"北京时间同步成功:{_currentBeijingTime:yyyy-MM-dd HH:mm:ss}"); OnTimeSynced?.Invoke(_currentBeijingTime); yield break; } } } catch (Exception e) { Debug.LogWarning($"解析失败:{e.Message}"); continue; } } } } Debug.LogError("所有时间服务器都失败了,使用本地时间"); _currentBeijingTime = DateTime.Now; _isTimeSynced = false; } /// /// 获取格式化的北京时间 /// public string GetFormattedTime(string format = "yyyy-MM-dd HH:mm:ss") { return CurrentBeijingTime.ToString(format); } }