windows日期同步

张开发
2026/4/14 11:49:32 15 分钟阅读

分享文章

windows日期同步
方式1以管理员身份运行cmd# 停止时间服务net stop w32time# 启动时间服务net start w32time# 输入命令触发强制同步w32tm /resync方式2C#代码实现usingSystem;usingSystem.Net;usingSystem.Net.Sockets;usingSystem.Runtime.InteropServices;namespacetimesync{internalclassProgram{staticvoidMain(string[]args){try{Console.WriteLine(正在连接NTP服务器获取标准时间...);varntpServerntp.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.orgDateTimentpUtcTimeGetNtpTime(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正在同步系统时间需管理员权限...);boolsyncSuccessSetLocalSystemTime(ntpUtcTime);if(syncSuccess){Console.WriteLine(✅ 系统时间同步成功);Console.WriteLine($当前系统本地时间{DateTime.Now});}else{interrorCodeMarshal.GetLastWin32Error();Console.WriteLine($❌ 系统时间同步失败错误码{errorCode}错误码5无管理员权限);}}catch(Exceptionex){Console.WriteLine($错误{ex.Message}\n{ex.StackTrace});}Console.ReadKey();}/// summary/// 从NTP服务器获取UTC标准时间修复字节序转换问题/// /summarypublicstaticDateTimeGetNtpTime(stringntpServercn.pool.ntp.org){// NTP协议数据包48字节LI0, VN3, Mode3客户端模式byte[]ntpDatanewbyte[48];ntpData[0]0x1B;// 解析NTP服务器IP并建立UDP连接IPAddress[]addressesDns.GetHostEntry(ntpServer).AddressList;IPEndPointipEndPointnewIPEndPoint(addresses[0],123);using(UdpClientudpClientnewUdpClient()){udpClient.Connect(ipEndPoint);udpClient.Send(ntpData,ntpData.Length);ntpDataudpClient.Receive(refipEndPoint);}// 解析NTP响应时间戳在第40-47字节32位整数部分 32位小数部分// 注意此处用uint32位而非ulong64位避免字节序转换错误uintintPartBitConverter.ToUInt32(ntpData,40);// 秒数大端序uintfracPartBitConverter.ToUInt32(ntpData,44);// 小数秒大端序// 修正针对32位uint的字节序转换大端→小端intPartSwapEndianness32(intPart);fracPartSwapEndianness32(fracPart);// 计算毫秒数避免溢出分步计算// NTP时间基准1900-01-01 00:00:00 UTClongtotalSeconds(long)intPart;longtotalMillisecondstotalSeconds*1000;// 秒转毫秒// 小数秒转毫秒fracPart是32位无符号数最大值0xFFFFFFFF对应1秒longfracMilliseconds(long)((fracPart*1000.0)/0x100000000L);totalMillisecondsfracMilliseconds;// 转换为DateTime严格指定UTCDateTimentpEpochnewDateTime(1900,1,1,0,0,0,DateTimeKind.Utc);// 安全添加毫秒校验范围if(totalMilliseconds(DateTime.MaxValue-ntpEpoch).TotalMillisecondstotalMilliseconds(DateTime.MinValue-ntpEpoch).TotalMilliseconds){returnntpEpoch.AddMilliseconds(totalMilliseconds);}else{thrownewArgumentOutOfRangeException(nameof(totalMilliseconds),$计算出的毫秒数{totalMilliseconds}超出DateTime合法范围);}}/// summary/// 修正32位无符号整数的字节序转换大端序→小端序/// /summaryprivatestaticuintSwapEndianness32(uintx){// 对32位uint的字节序反转例如0x12345678 → 0x78563412return((x0x000000FF)24)|((x0x0000FF00)8)|((x0x00FF0000)8)|((x0xFF000000)24);}/// summary/// 导入SetSystemTime API设置系统时间接收UTC时间/// /summary/// param namest/param/// returns/returns[DllImport(kernel32.dll,SetLastErrortrue)]publicstaticexternboolSetSystemTime(refSYSTEMTIMEst);/// summary/// 调用API设置系统时间接收UTC时间/// /summary/// param nameutcTimeUTC标准时间/param/// returns是否设置成功/returnspublicstaticboolSetLocalSystemTime(DateTimeutcTime){SYSTEMTIMEsystemTimenewSYSTEMTIME{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/// 年/// /summarypublicushortwYear;/// summary/// 月/// /summarypublicushortwMonth;/// summary/// 星期0周日6周六/// /summarypublicushortwDayOfWeek;/// summary/// 日/// /summarypublicushortwDay;/// summary/// 时UTC/// /summarypublicushortwHour;/// summary/// 分/// /summarypublicushortwMinute;/// summary/// 秒/// /summarypublicushortwSecond;/// summary/// 毫秒/// /summarypublicushortwMilliseconds;}}参考https://www.zhihu.com/question/30252609

更多文章