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}秒");
}
}