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

说明

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

问题分析

1、自己如果有服务器:自定义一个后端API,客户端按需请求就行了;

2、如果没有服务器(本篇文章主要讲解的内容):

a、可以使用别人的免费API,但是通常问题比较多,例如:服务器关闭了、API禁用了等(该方案有风险);

b、更稳妥点的方案:请求大厂服务器(例如:百度、腾讯、Github等),获取其响应头时间;

那么,我们应该选择稳妥一点的方案:b。

通过抓包工具,我们抓一下网络请求,分析一下响应头,如下图:

通过上图可知,我们只需要正常请求大厂的最常用的URL,等待响应成功后,读取响应头中的"Date"属性就行了。

代码实现

csharp 复制代码
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;
        }
}
相关推荐
EIP低代码平台1 小时前
EIP 低代码平台 - 角色维护
低代码·c#·权限·工作流·netcore
Yana.nice2 小时前
Linux 只保留 30 天内日志(find命令删除日志文件)
linux·运维·chrome
2601_960567965 小时前
电商套图自动化效率的工程量化分析——从逐张生成到批量套图的架构演进
运维·架构·自动化
吳所畏惧6 小时前
宝塔面板Redis密码修改指南:SSH命令修改 vs 面板UI界面修改,哪个更靠谱?
运维·服务器·数据库·redis·缓存·ssh
DFT计算杂谈6 小时前
无 Root 权限在 Tesla K80 零门槛部署 DeepSeek 大模型
linux·服务器·网络·数据库·机器学习
HiDev_6 小时前
【非标自动化】2、认识元器件(确定目标)
运维·自动化
心平气和量大福大6 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
维天说6 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json
Zhang~Ling7 小时前
从 fopen 到 struct file:从零开始拆解 Linux 文件 I/O
linux·运维·服务器
爱写代码的阿森7 小时前
鸿蒙三方库 | harmony-utils之PreferencesUtil首选项数据监听详解
服务器·华为·harmonyos·鸿蒙·huawei