• 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{
                    //重置状态
    
                }
    
            }
                
        }
    }
  • 相关阅读:
    mysql---面试题2
    Mysql--存储过程
    MySql--锁机制
    MYsql事务
    IDEA创建新项目保存pom文件时,出现错误Cannot resolve org.openjfx:javafx.base:11.0.0-SNAPSHOP
    线程中的多线程、并行和并发、同步和异步、阻塞和非阻塞、线程安全
    Java里的Arrays.asList()返回的List不能使用add、remove方法?
    服务器可用的Socket
    MessageBox.Show
    NPOI 教程
  • 原文地址:https://www.cnblogs.com/txfd/p/10051652.html
Copyright © 2020-2023  润新知