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));
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值