StableVersion4.3/HL_FristAidPlatform_Public/SystemTime.cs

113 lines
4.3 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
namespace HL_FristAidPlatform_Public
{
/// <summary>
/// 同步服务器时间
/// </summary>
public class SystemTime
{
[StructLayout(LayoutKind.Sequential)]
private struct NTPTime
{
public short year;
public short month;
public short dayOfWeek;
public short day;
public short hour;
public short minute;
public short second;
public short milliseconds;
}
[DllImport("kernel32.dll")]
private static extern bool SetLocalTime(ref NTPTime time);
private static uint swapEndian(ulong x)
{
return (uint)(((x & 0x000000ff) << 24) +
((x & 0x0000ff00) << 8) +
((x & 0x00ff0000) >> 8) +
((x & 0xff000000) >> 24));
}
/// <summary>
/// 设置系统时间
/// </summary>
/// <param name="dt">需要设置的时间</param>
/// <returns>返回系统时间设置状态true为成功false为失败</returns>
private static bool SetLocalDateTime(DateTime dt)
{
NTPTime st;
st.year = (short)dt.Year;
st.month = (short)dt.Month;
st.dayOfWeek = (short)dt.DayOfWeek;
st.day = (short)dt.Day;
st.hour = (short)dt.Hour;
st.minute = (short)dt.Minute;
st.second = (short)dt.Second;
st.milliseconds = (short)dt.Millisecond;
bool rt = SetLocalTime(ref st);
return rt;
}
public static bool Synchronization(string host, out DateTime syncDateTime, out string message)
{
syncDateTime = DateTime.Now;
message = "";
try
{
//if (iPAddress == null)
//{
// var iphostinfo = Dns.GetHostEntry(IPAddress.Parse(host));
// var ntpServer = iphostinfo.AddressList[0];
// iPAddress = ntpServer;
//}
DateTime dtStart = DateTime.Now;
//NTP消息大小摘要是16字节 (RFC 2030)
byte[] ntpData = new byte[48];
//设置跳跃指示器、版本号和模式值
// LI = 0 (no warning), VN = 3 (IPv4 only), Mode = 3 (Client Mode)
ntpData[0] = 0x1B;
IPAddress ip = IPAddress.Parse(host);
// NTP服务给UDP分配的端口号是123
IPEndPoint ipEndPoint = new IPEndPoint(ip, 123);
// 使用UTP进行通讯
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.Connect(ipEndPoint);
socket.ReceiveTimeout = 3000;
socket.Send(ntpData);
socket.Receive(ntpData);
socket?.Close();
socket?.Dispose();
DateTime dtEnd = DateTime.Now;
//传输时间戳字段偏移量以64位时间戳格式应答离开客户端服务器的时间
const byte serverReplyTime = 40;
// 获得秒的部分
ulong intPart = BitConverter.ToUInt32(ntpData, serverReplyTime);
//获取秒的部分
ulong fractPart = BitConverter.ToUInt32(ntpData, serverReplyTime + 4);
//由big-endian 到 little-endian的转换
intPart = swapEndian(intPart);
fractPart = swapEndian(fractPart);
ulong milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000UL);
// UTC时间
DateTime webTime = (new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc)).AddMilliseconds(milliseconds);
//本地时间
DateTime dt = webTime.ToLocalTime();
bool isSuccess = SetLocalDateTime(dt);
syncDateTime = dt;
}
catch (Exception ex)
{
message = ex.Message;
PublicClass.WriteErrorLog("一键校时", ex.Message);
return false;
}
return true;
}
}
}