186 lines
6.2 KiB
C#
186 lines
6.2 KiB
C#
using System;
|
|
using UnityEngine;
|
|
using System.Collections;
|
|
using UnityEngine.Networking;
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
/// <summary>
|
|
/// 北京时间管理器 - 获取一次后持续自增
|
|
/// </summary>
|
|
public class BeijingTimeManager : MonoSingleton<BeijingTimeManager>
|
|
{
|
|
[Header("时间状态")]
|
|
[SerializeField] private bool _isTimeSynced = false;
|
|
[SerializeField] private DateTime _currentBeijingTime;
|
|
[SerializeField] private float _timeSinceLastSync;
|
|
|
|
/// <summary>
|
|
/// 获取当前北京时间
|
|
/// </summary>
|
|
public DateTime CurrentBeijingTime
|
|
{
|
|
get
|
|
{
|
|
if (_isTimeSynced)
|
|
{
|
|
return _currentBeijingTime.AddSeconds(_timeSinceLastSync);
|
|
}
|
|
return DateTime.Now; // 未同步时返回本地时间
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取时间戳(秒)- 1970-01-01 08:00:00 到现在的秒数
|
|
/// </summary>
|
|
public long CurrentTimestamp
|
|
{
|
|
get
|
|
{
|
|
DateTime beijingTime = CurrentBeijingTime;
|
|
DateTime epoch = new DateTime(1970, 1, 1, 8, 0, 0); // 北京时间起点
|
|
return (long)(beijingTime - epoch).TotalSeconds;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取时间戳(毫秒)
|
|
/// </summary>
|
|
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<DateTime> OnTimeSynced;
|
|
|
|
private void Start()
|
|
{
|
|
SyncBeijingTime();
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (_isTimeSynced)
|
|
{
|
|
_timeSinceLastSync += Time.deltaTime;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 同步北京时间
|
|
/// </summary>
|
|
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;
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// 获取格式化的北京时间
|
|
/// </summary>
|
|
public string GetFormattedTime(string format = "yyyy-MM-dd HH:mm:ss")
|
|
{
|
|
return CurrentBeijingTime.ToString(format);
|
|
}
|
|
} |