最初通過qq時間服務器獲得時間,經常出現有網絡也獲取失敗的情況。
后面尋找解決辦法,查找資料終於發現通過ntp時間服務器獲取網絡時間的方法。
首先游戲開始獲得初始化網絡時間,通常只獲取一次,其他時間獲取時間通過本地時間差加上初始網絡時間獲得當前時間。
GetCurrentTime()獲取當前時間,GetDay()獲得當前天數整點。
代碼如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using System.Net; using System.Net.Sockets; namespace NTP { public class NetworkTime { private static NetworkTime instance; private static readonly object locker = new object(); private NetworkTime(){ } public static NetworkTime GetInstance(){ if (instance == null) { lock (locker) { if (instance == null) { instance = new NetworkTime (); } } } return instance; } public void InitTime(){ GetNetworkTime (); } public string TIME_SERVER_URL = "ntp7.aliyun.com"; public DateTime initTime,initLocalTime; public static DateTime InsteadLocalTime; public static string InsteadLocalTime_st; public DateTime GetNetworkTime() { try { //ntp服務器地址 string server = TIME_SERVER_URL; var ntpData = new byte[48]; ntpData[0] = 0x1B; //網絡鏈接 var addresses = Dns.GetHostEntry(server).AddressList; var ipEndPoint = new IPEndPoint(addresses[0], 123); // https port : 443 var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); socket.ReceiveTimeout = 5000; socket.Connect(ipEndPoint); socket.Send(ntpData); socket.Receive(ntpData); socket.Close(); ulong intPart = (ulong)ntpData[40] << 24 | (ulong)ntpData[41] << 16 | (ulong)ntpData[42] << 8 | (ulong)ntpData[43]; ulong fractPart = (ulong)ntpData[44] << 24 | (ulong)ntpData[45] << 16 | (ulong)ntpData[46] << 8 | (ulong)ntpData[47]; var milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L); var networkDataTime = (new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Local)).AddMilliseconds((long)milliseconds); TimeZone localzone = TimeZone.CurrentTimeZone; TimeSpan currentOffset = localzone.GetUtcOffset(networkDataTime); initTime = networkDataTime + currentOffset; initLocalTime = DateTime.Now; Debug.Log("steve" + initTime.ToString()); return initTime; } catch { InsteadLocalTime = DateTime.UtcNow; TimeZone localzone_ = TimeZone.CurrentTimeZone; TimeSpan currentOffset_ = localzone_.GetUtcOffset(DateTime.UtcNow); initTime = DateTime.UtcNow + currentOffset_;//기준 시에 +,- 로컬과 시간차이 더하면 현지로컬시간이 나옴! return initTime; } } public DateTime GetDay(int day = 0){ return GetCurrentTime().AddDays(day).Date; } public DateTime GetCurrentTime(){ DateTime d = DateTime.Now; return initTime + (d - initLocalTime); } public void CompareGameTime(){ //時間的比較,一般用於連續簽到系統等 string SavedAfterDayTime = PlayerPrefs.GetString("SavedAfterDayTime", "11/30/2018 00:00:00 AM"); //轉化成第一個時間點(即領取后的第一天) DateTime SavedAfterDayTime_T = Convert.ToDateTime(SavedAfterDayTime); //當前時間與時間點相比較,當前時間超過存檔錢則等於1,相等則等於0,當前時間未超過存檔點的時間則等於-1 int compare1 = DateTime.Compare(GetDay(), SavedAfterDayTime_T.Date); if(compare1 < 0){ //開啟倒計時 }else if(compare1 == 0){ //待領取,計時器結束 }else{ //重置狀態 } } } }