C#修改Windows系统时间

1. 修改系统时间的Windows 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个小时。


2. 相关结构struct类型

[StructLayout(LayoutKind.Sequential)]
struct SystemTime
{
    [MarshalAs(UnmanagedType.U2)]
    internal ushort year; // 年
    [MarshalAs(UnmanagedType.U2)]
    internal ushort month; // 月
    [MarshalAs(UnmanagedType.U2)]
    internal ushort dayOfWeek; // 星期
    [MarshalAs(UnmanagedType.U2)]
    internal ushort day; // 日
    [MarshalAs(UnmanagedType.U2)]
    internal ushort hour; // 时
    [MarshalAs(UnmanagedType.U2)]
    internal ushort minute; // 分
    [MarshalAs(UnmanagedType.U2)]
    internal ushort second; // 秒
    [MarshalAs(UnmanagedType.U2)]
    internal ushort milliseconds; // 毫秒
}

3. 调用Windows API实现本地/系统时间的获取与修改

/// 
/// 获取本地时间
/// 
/// 
public DateTime getLocalTime()
{
    SystemTime sysTime = new SystemTime();
    GetLocalTime(ref sysTime);
    return SystemTime2DateTime(sysTime);
}

/// 
/// 设置本地时间
/// 
/// 
/// 
public bool setLocalTime(DateTime dateTime)
{
    if (grantPrivilege(SE_SYSTEMTIME_NAME))
    {
        // 授权成功
        SystemTime sysTime = DateTime2SystemTime(dateTime);
        bool success = SetLocalTime(ref sysTime);
        if (!revokePrivilege(SE_SYSTEMTIME_NAME))
        {
            // 撤权失败
        }
        return success;
    }
    // 授权失败
    return false;
}

/// 
/// 获取系统时间
/// 
/// 
public DateTime getSystemTime()
{
    SystemTime sysTime = new SystemTime();
    GetSystemTime(ref sysTime);
    return SystemTime2DateTime(sysTime);
}

/// 
/// 设置系统时间(UTC)
/// 
/// 
/// 
public bool setSystemTime(DateTime dateTime)
{
    if (grantPrivilege(SE_SYSTEMTIME_NAME))
    {
        // 授权成功
        SystemTime sysTime = DateTime2SystemTime(dateTime);
        bool success = SetSystemTime(ref sysTime);
        if (!revokePrivilege(SE_SYSTEMTIME_NAME))
        {
            // 撤权失败
        }
        return success;
    }
    // 授权失败
    return false;
}

/// 
/// 将SystemTime转换为DateTime
/// 
/// 
/// 
public DateTime SystemTime2DateTime(SystemTime sysTime)
{
    return new DateTime(sysTime.year, sysTime.month, sysTime.day, sysTime.hour, sysTime.minute, sysTime.second, sysTime.milliseconds);
}

/// 
/// 将DateTime转换为SystemTime
/// 
/// 
/// 
public SystemTime DateTime2SystemTime(DateTime dateTime)
{
    SystemTime sysTime = new SystemTime();
    sysTime.year = Convert.ToUInt16(dateTime.Year);
    sysTime.month = Convert.ToUInt16(dateTime.Month);
    sysTime.day = Convert.ToUInt16(dateTime.Day);
    sysTime.hour = Convert.ToUInt16(dateTime.Hour);
    sysTime.minute = Convert.ToUInt16(dateTime.Minute);
    sysTime.second = Convert.ToUInt16(dateTime.Second);
    sysTime.milliseconds = Convert.ToUInt16(dateTime.Millisecond);
    return sysTime;
}

4. 自动同步本地时间

从NTP服务器获取时间,并自动修改本地时间,即可以实现自动同步本地时间。关于如何从NTP服务器获取时间,可以参考:从NTP服务器获取时间(C#)

5. 注意事项:

① 上述代码中的grantPrivilege(SE_SYSTEMTIME_NAME)和revokePrivilege(SE_SYSTEMTIME_NAME)用于授予/撤销进程修改时间的权限,这里没有给出具体的代码;

② 可以参考子丰的博文:点击打开链接

③ 也可以直接下载代码:点击打开链接

④ 也可以直接删除上面授权和撤权的代码,以管理员身份运行程序也能修改时间。

你可能感兴趣的:(程序)