C# .NET Framework 4.8 修改/校正系统当前时间完整实现
前置说明
一、完整工具类(Win32 API封装)
using System;
using System.Runtime.InteropServices;
namespace TimeCalibrateDemo
{
/// <summary>
/// Windows系统时间校正工具(.NET4.8)
/// </summary>
public static class SystemTimeHelper
{
// Win32 系统时间结构体
[StructLayout(LayoutKind.Sequential)]
private 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 wMilliseconds;
}
// 设置系统本地时间API
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool SetLocalTime(ref SYSTEMTIME lpSystemTime);
// 获取本地系统时间
[DllImport("kernel32.dll")]
private static extern void GetLocalTime(out SYSTEMTIME lpSystemTime);
/// <summary>
/// 校正系统日期+时间
/// </summary>
/// <param name="targetTime">目标标准时间</param>
/// <returns>true=成功;false=失败(无管理员权限/参数错误)</returns>
public static bool SetSystemDateTime(DateTime targetTime)
{
SYSTEMTIME st = new SYSTEMTIME
{
wYear = (ushort)targetTime.Year,
wMonth = (ushort)targetTime.Month,
wDay = (ushort)targetTime.Day,
wHour = (ushort)targetTime.Hour,
wMinute = (ushort)targetTime.Minute,
wSecond = (ushort)targetTime.Second,
wMilliseconds = (ushort)targetTime.Millisecond
};
// DayOfWeek由系统自动填充,无需手动赋值
bool result = SetLocalTime(ref st);
if (!result)
{
int err = Marshal.GetLastWin32Error();
Console.WriteLine($"设置时间失败,Win32错误码:{err}");
}
return result;
}
/// <summary>
/// 仅校正时分秒,保留当前系统年月日
/// </summary>
/// <param name="hour">时 0-23</param>
/// <param name="minute">分 0-59</param>
/// <param name="second">秒 0-59</param>
public static bool SetSystemTimeOnly(int hour, int minute, int second)
{
GetLocalTime(out SYSTEMTIME st);
st.wHour = (ushort)hour;
st.wMinute = (ushort)minute;
st.wSecond = (ushort)second;
st.wMilliseconds = 0;
return SetLocalTime(ref st);
}
}
}
二、调用示例
class Program
{
static void Main(string[] args)
{
// 示例1:直接设置完整标准时间(服务器同步时间)
DateTime standardTime = new DateTime(2026, 7, 20, 15, 30, 0);
bool ok1 = SystemTimeHelper.SetSystemDateTime(standardTime);
Console.WriteLine(ok1 ? "时间校正成功" : "校正失败,请以管理员身份运行程序");
// 示例2:只修改时分秒,日期不变
bool ok2 = SystemTimeHelper.SetSystemTimeOnly(16, 20, 10);
}
}
三、关键配套:程序自动请求管理员权限
方法1:app.manifest 配置(推荐,双击直接提权)
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
方法2:代码运行时检测权限,无权限自动重启程序
using System.Diagnostics;
using System.Security.Principal;
public static bool IsRunAsAdmin()
{
WindowsIdentity id = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(id);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
// 在Main开头调用
static void Main(string[] args)
{
if (!IsRunAsAdmin())
{
Process proc = new Process();
proc.StartInfo.FileName = Process.GetCurrentProcess().MainModule.FileName;
proc.StartInfo.Verb = "runas"; // 以管理员启动
proc.Start();
return;
}
// 下方放校正时间逻辑
}
四、常见问题说明
未配置manifest、未右键“以管理员身份运行”,必须提权才能修改系统时钟。
SetLocalTime 修改本地时区时间;如需UTC时间使用 SetSystemTime API(结构体字段含义一致)。
企业电脑由域服务器管控时间,程序修改会被自动覆盖,需放开组策略权限。
.NET4.8 完全兼容,API无版本限制。
五、扩展:NTP网络时间自动校正(搭配使用)
如需从互联网标准时间同步再设置本地时钟,可增加NTP客户端解析UTC时间,再转换本地DateTime传入SetSystemDateTime。
需要我补充一段NTP授时完整代码吗?
![set 与 map :从 [] 暗坑到严格弱序,把有序关联容器用明白-171主机测评](https://www.171host.com/wp-content/uploads/2026/10/20261031153944-6ae60bc0ee6df-220x150.png)
