• Unity3D获得服务器时间/网络时间/后端时间/ServerTime,适合单机游戏使用


    说明

    一些游戏开发者在做单机游戏功能时(例如:每日奖励、签到等),可能会需要获得服务端标准时间,用于游戏功能的逻辑处理。

    问题分析

    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
    {
    	void Start ()
    	{
    		getServerTime ();
    	}
    
    	//获得服务器时间
    	public void getServerTime ()
    	{
    		string url1 = "https://www.baidu.com";
    		StartCoroutine (IServerTime (url1));
    
    		string url2 = "https://blog.csdn.net";
    		StartCoroutine (IServerTime (url2));
    
    		string url3 = "https://www.jianshu.com";
    		StartCoroutine (IServerTime (url3));
    
    		string url4 = "https://github.com";
    		StartCoroutine (IServerTime (url4));
    
    		string url5 = "https://www.sohu.com";
    		StartCoroutine (IServerTime (url5));
    	}
    
    	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;
    			}
    
    			//打印格林威治时间
    			Debug.Log (url+" 的 GMT DATE : "+value);
    
    			//打印本地时间(东八区)
    			Debug.Log (url+" 的 北京时间:"+ GMT2Local(value));
    		}
    	}
    
    	/// <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;
    	}
    }
    

    将脚本挂载到Unity游戏对象上,运行游戏,查看日志输出,如下图:

    总结

    该实现方案,非常简单实用,大家也无需担心大厂倒闭。

    通过响应头取出来的时间,默认是格林威治时间(GMT)。
    上面案例中,已做了格林威治时间转换为东八区时间(北京时间),如果大家做的游戏是要发布到全世界的,最好再根据不同国家的时区,进行计算一下。

  • 相关阅读:
    百度地图(8)-图层
    百度地图(7)-点聚合
    百度地图(6)-信息窗口
    鸟哥学习笔记二(基础篇第七章)
    鸟哥学习笔记一(基础篇第六章)
    sql server学习笔记二
    sql server学习笔记一
    centos下sudo命令不能使用
    CentOS系统时间与现在时间相差8小时解决方法
    SUID GUID详解
  • 原文地址:https://www.cnblogs.com/qixingchao/p/13665499.html
Copyright © 2020-2023  润新知