c# 设置系统时间本地时间(客户端与NTP服务器端,使用UDP 123端口对设备提供时钟同步服务)

【使用管理员权限执行】

调用系统api

[DllImport("Kernel32.dll")]
public static extern void GetLocalTime(ref SystemTime lpSystemTime);

 [DllImport("Kernel32.dll")]
 public static extern bool SetLocalTime(ref SystemTime lpSystemTime);

 [DllImport("Kernel32.dll")]
 public static extern void GetSystemTime(ref SystemTime lpSystemTime);

 [DllImport("Kernel32.dll")]
  public static extern bool SetSystemTime(ref SystemTime lpSystemTime);

注:

① 前两个API为获取本地时间和设置本地时间,后两个API为获取系统时间和设置系统时间。

② 其区别在于系统时间为UTC时间,本地时间为我们在计算机上实际看到的时间。

③ 若计算机的时区设置为中国,则本地时间就是北京时间,其与系统时间相差8个小时。

统一结构体

 [StructLayout(LayoutKind.Sequential)]
        public struct SystemTime
        {
            public ushort wYear;
            public ushort wMonth;
            public ushort wDayOfWeek;
            public ushort wDay;
            public ushort wHour;
            public ushort wMinute;
            public ushort wSecond;
            public ushort wMiliseconds;
        }

接口方法

public void getWebTime() {
            // default ntp server
            const string ntpServer = "ntp1.aliyun.com";

            // NTP message size - 16 bytes of the digest (RFC 2030)
            byte[] ntpData = new byte[48];
            // Setting the Leap Indicator, Version Number and Mode values
            ntpData[0] = 0x1B; // LI = 0 (no warning), VN = 3 (IPv4 only), Mode = 3 (Client Mode)

            IPAddress[] addresses = Dns.GetHostEntry(ntpServer).AddressList;
            // The UDP port number assigned to NTP is 123
            IPEndPoint ipEndPoint = new IPEndPoint(addresses[0], 123);

            // NTP uses UDP
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            socket.Connect(ipEndPoint);
            // Stops code hang if NTP is blocked
            socket.ReceiveTimeout = 3000;
            socket.Send(ntpData);
            socket.Receive(ntpData);
            socket.Close();

            // Offset to get to the "Transmit Timestamp" field (time at which the reply 
            // departed the server for the client, in 64-bit timestamp format."
            const byte serverReplyTime = 40;
            // Get the seconds part
            ulong intPart = BitConverter.ToUInt32(ntpData, serverReplyTime);
            // Get the seconds fraction
            ulong fractPart = BitConverter.ToUInt32(ntpData, serverReplyTime + 4);
            // Convert From big-endian to little-endian
            intPart = swapEndian(intPart);
            fractPart = swapEndian(fractPart);
            ulong milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000UL);

            // UTC time
            DateTime webTime = (new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc)).AddMilliseconds(milliseconds);
            string localTime = DateTime.Now.ToString("yyyyMMddHHmmss");
            // Local time

            DateTime dt = webTime.ToLocalTime();
           
            SyncTime(dt);

        }

        // 小端存储与大端存储的转换
        private uint swapEndian(ulong x)
        {
            return (uint)(((x & 0x000000ff) << 24) +
            ((x & 0x0000ff00) << 8) +
            ((x & 0x00ff0000) >> 8) +
            ((x & 0xff000000) >> 24));
        }

 /// <summary> 
        /// 设置系统时间 
        /// </summary> 
        public static Boolean SyncTime(DateTime currentTime)
        {
            Boolean flag = false;
            try
            {
                SystemTime sysTime = new SystemTime();
                sysTime.wYear = Convert.ToUInt16(currentTime.Year);
                sysTime.wMonth = Convert.ToUInt16(currentTime.Month);
                sysTime.wDay = Convert.ToUInt16(currentTime.Day);
                sysTime.wDayOfWeek = Convert.ToUInt16(currentTime.DayOfWeek);
                sysTime.wMinute = Convert.ToUInt16(currentTime.Minute);
                sysTime.wSecond = Convert.ToUInt16(currentTime.Second);
                sysTime.wMiliseconds = Convert.ToUInt16(currentTime.Millisecond); 
                sysTime.wHour = Convert.ToUInt16(currentTime.Hour);

                SetLocalTime(ref sysTime);//设置本机时间
                flag = true;
            }
            catch (Exception)
            {

                flag = false;
            }
            return flag;
        }


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值