【使用管理员权限执行】
调用系统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;
}