【问题标题】:How will I set system time regardless of UTC?无论UTC如何,我将如何设置系统时间?
【发布时间】:2018-10-04 08:12:34
【问题描述】:

我已经获得了以下代码: Change system date programmatically

我有一个按钮,当我单击时必须更新系统时间。但是发生的事情是我没有得到我想要的结果。

正如您在下面的代码中看到的,我将日期和时间设置为 2018 年 4 月 25 日上午 1:00:00,但我得到的是 2018 年 4 月 25 日 9:00 :00 AM 因为 UTC 增加了时间,在我的时区是 +8。

如何将系统时间直接设置为1:00:00AM

[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 wMilliseconds;
}

[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool SetSystemTime(ref SYSTEMTIME st);

private void UpdateSystemTime(DateTime dt)
{
    SYSTEMTIME st = new SYSTEMTIME();
    st.wYear = (ushort)dt.Year;
    st.wMonth = (ushort)dt.Month;
    st.wDay = (ushort)dt.Day;
    st.wHour = (ushort)dt.Hour;
    st.wMinute = (ushort)dt.Minute;
    st.wSecond = (ushort)dt.Second;

    SetSystemTime(ref st); // invoke this method.
}

private void Button1_Click(object sender, RoutedEventArgs e)
{
    timeToSet = new DateTime(year, month, day, hour, minute, second, second, DateTimeKind.Utc);
    UpdateSystemTime(timeToSet);
}

【问题讨论】:

  • 您为什么要尝试以编程方式设置系统时间?所有现代 Windows 操作系统都能够自动设置时间。除非该设置被禁用(它不应该被禁用),否则当时钟再次同步时,您通过此处的代码所做的任何调整最终都会被覆盖。
  • 我正在开发的应用程序将是唯一可以在操作系统上运行的应用程序,并且大多数功能将被禁用,包括 win explorer,因此用户可以修改时间的唯一方法是通过应用程序。我将使用 Windows 10 作为其基本操作系统。顺便说一句,您对如何安全地启用/禁用 Windows 自动时间同步有什么建议吗?
  • 这是设置页面中的第一个设置,但除非您完全断开与所有网络的连接,否则我强烈建议您保持打开状态并自动设置时间。很多事情没有准确的时间就失败了。例如,SSL 证书有过期日期,而 Kerberos 身份验证只有 5 分钟的容限。许多其他事情......
  • 很抱歉,我没有说明如何禁用/启用自动同步。由于 Windows 10 的大部分 UI 都将被禁用,我想通过代码完成所有这些过程。因为在我的应用程序的时间设置中,会有一个选项是否自动更新时间。这是我第一次通过代码访问系统的日期/时间,所以请告诉我如何正确操作。
  • 您需要禁用 Windows 时间服务,如果您搜索,StackOverflow 上的其他答案会显示给您。同样,我建议不要这样做。

标签: c# .net datetime time system


【解决方案1】:

查看SetSystemTimedocumentation

设置当前系统时间和日期。系统时间以协调世界时 (UTC) 表示。

这意味着您必须传递 UTC,而不是本地时间(或传递的时间被解释为 UTC)。

当您创建DateTime 对象时,您传递了DateTimeKind.Utc,但这并不意味着您传递的值从本地时间转换为UTC 时间,而是DateTime 对象被创建为UTC 时间目的。当您将 1 AM 作为小时传递时,当您调用 dt.Hour 时,您仍然会得到 1 AM,它被传递给 SetSystemTime 并解释为 1 AM UTC,而不是当地时间 1 AM

如何克服这个问题?

您必须为本地时间创建一个 DateTime,将其转换为 UTC,然后将值传递给 SetSystemTime

timeToSet = new DateTime(year, month, day, hour, minute, second, second, DateTimeKind.Local);
UpdateSystemTime(timeToSet.ToUniversalTime()); // this converts the local DateTime object to UTC

【讨论】:

  • 现在可以正常使用了。谢谢!但万一我现在改变了我的时区。使用这段代码会不会有什么问题?
  • DateTimeKind.Local 将始终根据您的系统设置参考本地时间,因此在任何情况下转换为 UTC 都应该是正确的。
  • 请记住,如果系统设置中的时区“错误”,则时间将设置为“错误”值,但您无能为力(系统实际上是“对程序撒谎)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-22
  • 2011-09-06
  • 2013-05-07
  • 2010-11-28
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多