说明
一些游戏开发者在做单机游戏功能时(例如:每日奖励、签到等),可能会需要获得服务端标准时间,用于游戏功能的逻辑处理。
问题分析
1、自己如果有服务器:自定义一个后端API,客户端按需请求就行了;
2、如果没有服务器(本篇文章主要讲解的内容):
a、可以使用别人的免费API,但是通常问题比较多,例如:服务器关闭了、API禁用了等(该方案有风险);
b、更稳妥点的方案:请求大厂服务器(例如:百度、腾讯、Github等),获取其响应头时间;
那么,我们应该选择稳妥一点的方案:b。
通过抓包工具,我们抓一下网络请求,分析一下响应头,如下图:
通过上图可知,我们只需要正常请求大厂的最常用的URL,等待响应成功后,读取响应头中的“Date”属性就行了。
代码实现
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;public class TestDate : MonoBehaviour
{TimeSpan NowOffestTime=TimeSpan.Zero;void Start (){getServerTime ();}/// <summary>/// 获取实际的网络时间 切系统时间也没用/// </summary>/// <returns></returns>public static DateTime GetNowTime(){return DateTime.Now - NowOffestTime;}//获得服务器时间public void getServerTime (){string url = "https://github.com";StartCoroutine (IServerTime (url));}IEnumerator IServerTime (string url){Debug.Log ("开始获取“+url+”的服务器时间(GMT DATE)");WWW www = new WWW (url);yield return www;if (www.isDone && string.IsNullOrEmpty (www.error)) {Dictionary<string,string> resHeaders = www.responseHeaders;string key = "DATE";string value = null;if(resHeaders!=null && resHeaders.ContainsKey(key)){resHeaders.TryGetValue (key,out value);}if(value==null){Debug.Log ("DATE is null");yield break;}DateTime Gmt = GMT2Local(value);DateTime now = DateTime.Now;Debug.LogError($"本地时间: {Gmt}");Debug.LogError($"GMT转化本地时间: {Gmt}");Debug.LogError($"GMT时间: {(value)}");if (IsNewerHour(now,Gmt))//只要用户调的时间差在一个小时内都能接受{//记录一下时间差 这就是用户手动改的时间与世界时间的间隔//之后调用GetNowTime()就是准确时间NowOffestTime= now-Gmt ;}}}/// <summary>/// GMT时间转成本地时间全世界各个时区都会自动转换/// </summary>/// <param name="gmt">字符串形式的GMT时间</param>/// <returns></returns>public DateTime GMT2Local(string gmt){DateTime dt = DateTime.MinValue;try{string pattern = "";if (gmt.IndexOf("+0") != -1){gmt = gmt.Replace("GMT", "");pattern = "ddd, dd MMM yyyy HH':'mm':'ss zzz";}if (gmt.ToUpper().IndexOf("GMT") != -1){pattern = "ddd, dd MMM yyyy HH':'mm':'ss 'GMT'";}if (pattern != ""){dt = DateTime.ParseExact(gmt, pattern, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AdjustToUniversal);dt = dt.ToLocalTime();}else{dt = Convert.ToDateTime(gmt);}}catch{}return dt;}/// <summary>/// time0:当下的日子/// time1:被比较的日子/// </summary>/// <param name="time0"></param>/// <param name="time1"></param>/// <returns></returns>public static bool IsNewerHour(DateTime time0, DateTime time1){bool isNewer = false;if (time0 > time1) { if(time0.Year>time1.Year)isNewer = true;if (time0.Month > time1.Month)isNewer = true;if (time0.Day > time1.Day)isNewer = true;if (time0.Hour > time1.Hour)isNewer = true;}return isNewer;}
}