Unity通過NTP獲取網絡時間


最初通過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{
                //重置狀態

            }

        }
            
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM