Unity联网状态下获取网络时间否则获取本地时间,用于Unity程序倒计时和显示时间

using System;
using System.Net;
using UnityEngine;

public class GetCurrentTime : MonoBehaviour
{
    
    
    private void Start()
    {
    
    
        DateTime currentTime;

        if (Application.internetReachability != NetworkReachability.NotReachable)
        {
    
    
            // 如果连接到互联网,则获取网络时间
            currentTime = GetNetworkTime();
        }
        else
        {
    
    
            // 如果没有连接到互联网,则获取本地时间
            currentTime = DateTime.Now;
        }

        Debug.Log("当前时间:" + currentTime);
    }

    private DateTime GetNetworkTime()
    {
    
    
        try
        {
    
    
            // 从 NTP Pool Project 获取网络时间
            const string ntpServer = "pool.ntp.org";
            var ntpData = new byte[48];// 创建一个 48 字节大小的字节数组来存储 NTP 数据
            ntpData[0] = 0x1B;// 将 NTP 数据的第一个字节设置为 0x1B,这是 NTP 协议的请求数据格式

            var addresses = Dns.GetHostEntry(ntpServer).AddressList;// 获取 NTP 服务器的 IP 地址列表
            var ipEndPoint = new IPEndPoint(addresses[0], 123);// 创建用于连接的 IP 端点,使用第一个 IP 地址和 NTP 服务器的端口 123
            var socket = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);// 创建套接字,使用 IPv4 地址族、数据报套接字类型和 UDP 协议类型

            socket.Connect(ipEndPoint);// 连接到 NTP 服务器
            socket.Send(ntpData);// 发送 NTP 数据
            socket.Receive(ntpData);// 接收 NTP 响应数据
            socket.Close();// 关闭套接字连接

            const byte serverReplyTime = 40;// 服务器响应时间在 NTP 数据中的偏移量
            ulong intPart = BitConverter.ToUInt32(ntpData, serverReplyTime);// 从 NTP 数据中获取无符号 32 位整数部分
            ulong fractPart = BitConverter.ToUInt32(ntpData, serverReplyTime + 4);// 从 NTP 数据中获取无符号 32 位小数部分
             // 交换整数部分和小数部分的字节顺序,以适应本地字节顺序
            intPart = SwapEndianness(intPart);
            fractPart = SwapEndianness(fractPart);
           
            var milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L);// 将整数部分和小数部分转换为毫秒数
            var networkDateTime = (new DateTime(1900, 1, 1)).AddMilliseconds((long)milliseconds);// 根据毫秒数计算网络时间(从 1900 年 1 月 1 日开始计算)

            return networkDateTime;
        }
        catch (Exception e)
        {
    
    
            Debug.LogWarning("获取网络时间失败: " + e.Message);
            return DateTime.Now;
        }
    }
 // 交换字节顺序,将大端序转换为小端序或反之
    private static uint SwapEndianness(ulong x)
    {
    
    
        return (uint)(((x & 0x000000ff) << 24) +
                       ((x & 0x0000ff00) << 8) +
                       ((x & 0x00ff0000) >> 8) +
                       ((x & 0xff000000) >> 24));
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_44047050/article/details/131592458