方式1
以管理员身份运行cmd
# 停止时间服务net stop w32time# 启动时间服务net start w32time# 输入命令触发强制同步w32tm /resync方式2
C#代码实现
usingSystem;usingSystem.Net;usingSystem.Net.Sockets;usingSystem.Runtime.InteropServices;namespacetimesync{internalclassProgram{staticvoidMain(string[]args){try{Console.WriteLine("正在连接NTP服务器获取标准时间...");varntpServer="ntp.aliyun.com";//https://www.ntppool.org/zh///ntpServer ="cn.pool.ntp.org";//ntpServer ="time.edu.cn";//ntpServer ="ntp.tencent.com";//time.google.com//time.cloudflare.com//pool.ntp.orgDateTimentpUtcTime=GetNtpTime(ntpServer);Console.WriteLine($"获取到NTP UTC时间:{ntpUtcTime:yyyy-MM-dd HH:mm:ss.fff}");Console.WriteLine($"对应本地时间:{ntpUtcTime.ToLocalTime():yyyy-MM-dd HH:mm:ss.fff}");Console.WriteLine("\n正在同步系统时间(需管理员权限)...");boolsyncSuccess=SetLocalSystemTime(ntpUtcTime);if(syncSuccess){Console.WriteLine("✅ 系统时间同步成功!");Console.WriteLine($"当前系统本地时间:{DateTime.Now}");}else{interrorCode=Marshal.GetLastWin32Error();Console.WriteLine($"❌ 系统时间同步失败!错误码:{errorCode}(错误码5=无管理员权限)");}}catch(Exceptionex){Console.WriteLine($"错误:{ex.Message}\n{ex.StackTrace}");}Console.ReadKey();}/// <summary>/// 从NTP服务器获取UTC标准时间(修复字节序转换问题)/// </summary>publicstaticDateTimeGetNtpTime(stringntpServer="cn.pool.ntp.org"){// NTP协议数据包(48字节,LI=0, VN=3, Mode=3(客户端模式))byte[]ntpData=newbyte[48];ntpData[0]=0x1B;// 解析NTP服务器IP并建立UDP连接IPAddress[]addresses=Dns.GetHostEntry(ntpServer).AddressList;IPEndPointipEndPoint=newIPEndPoint(addresses[0],123);using(UdpClientudpClient=newUdpClient()){udpClient.Connect(ipEndPoint);udpClient.Send(ntpData,ntpData.Length);ntpData=udpClient.Receive(refipEndPoint);}// 解析NTP响应:时间戳在第40-47字节(32位整数部分 + 32位小数部分)// 注意:此处用uint(32位)而非ulong(64位),避免字节序转换错误uintintPart=BitConverter.ToUInt32(ntpData,40);// 秒数(大端序)uintfracPart=BitConverter.ToUInt32(ntpData,44);// 小数秒(大端序)// 修正:针对32位uint的字节序转换(大端→小端)intPart=SwapEndianness32(intPart);fracPart=SwapEndianness32(fracPart);// 计算毫秒数(避免溢出,分步计算)// NTP时间基准:1900-01-01 00:00:00 UTClongtotalSeconds=(long)intPart;longtotalMilliseconds=totalSeconds*1000;// 秒转毫秒// 小数秒转毫秒(fracPart是32位无符号数,最大值0xFFFFFFFF,对应1秒)longfracMilliseconds=(long)((fracPart*1000.0)/0x100000000L);totalMilliseconds+=fracMilliseconds;// 转换为DateTime(严格指定UTC)DateTimentpEpoch=newDateTime(1900,1,1,0,0,0,DateTimeKind.Utc);// 安全添加毫秒(校验范围)if(totalMilliseconds<(DateTime.MaxValue-ntpEpoch).TotalMilliseconds&&totalMilliseconds>(DateTime.MinValue-ntpEpoch).TotalMilliseconds){returnntpEpoch.AddMilliseconds(totalMilliseconds);}else{thrownewArgumentOutOfRangeException(nameof(totalMilliseconds),$"计算出的毫秒数{totalMilliseconds}超出DateTime合法范围");}}/// <summary>/// 修正:32位无符号整数的字节序转换(大端序→小端序)/// </summary>privatestaticuintSwapEndianness32(uintx){// 对32位uint的字节序反转(例如:0x12345678 → 0x78563412)return((x&0x000000FF)<<24)|((x&0x0000FF00)<<8)|((x&0x00FF0000)>>8)|((x&0xFF000000)>>24);}/// <summary>/// 导入SetSystemTime API(设置系统时间,接收UTC时间)/// </summary>/// <param name="st"></param>/// <returns></returns>[DllImport("kernel32.dll",SetLastError=true)]publicstaticexternboolSetSystemTime(refSYSTEMTIMEst);/// <summary>/// 调用API设置系统时间(接收UTC时间)/// </summary>/// <param name="utcTime">UTC标准时间</param>/// <returns>是否设置成功</returns>publicstaticboolSetLocalSystemTime(DateTimeutcTime){SYSTEMTIMEsystemTime=newSYSTEMTIME{wYear=(ushort)utcTime.Year,wMonth=(ushort)utcTime.Month,wDay=(ushort)utcTime.Day,wHour=(ushort)utcTime.Hour,wMinute=(ushort)utcTime.Minute,wSecond=(ushort)utcTime.Second,wMilliseconds=(ushort)utcTime.Millisecond};returnSetSystemTime(refsystemTime);}}/// <summary>/// 定义Windows API所需的SYSTEMTIME结构体(对应系统时间格式)/// </summary>[StructLayout(LayoutKind.Sequential)]publicstructSYSTEMTIME{/// <summary>/// 年/// </summary>publicushortwYear;/// <summary>/// 月/// </summary>publicushortwMonth;/// <summary>/// 星期(0=周日,6=周六)/// </summary>publicushortwDayOfWeek;/// <summary>/// 日/// </summary>publicushortwDay;/// <summary>/// 时(UTC)/// </summary>publicushortwHour;/// <summary>/// 分/// </summary>publicushortwMinute;/// <summary>/// 秒/// </summary>publicushortwSecond;/// <summary>/// 毫秒/// </summary>publicushortwMilliseconds;}}参考
https://www.zhihu.com/question/30252609