SetSystemTime kernel32 中的奇怪行为

Posted

技术标签:

【中文标题】SetSystemTime kernel32 中的奇怪行为【英文标题】:Strange behaviour in SetSystemTime kernel32 【发布时间】:2014-09-30 10:58:37 【问题描述】:

我有以下代码:

Public Class SetSystemTime
    Structure SYSTEMTIME
        Public wYear As Short
        Public wMonth As Short
        Public wDayOfWeek As Short
        Public wDay As Short
        Public wHour As Short
        Public wMinute As Short
        Public wSecond As Short
        Public wMilliseconds As Short
    End Structure

    Public Declare Function SetSystemTime Lib "kernel32" (ByRef lpSystemTime As SYSTEMTIME) As Boolean
End Class

Private Sub SetDateTime(dt As DateTime)
    Dim dateTimeStruct As SetSystemTime.SYSTEMTIME
    Dim incHour As Integer = DateDiff(DateInterval.Hour, Now, Date.UtcNow)

    With dateTimeStruct
        .wDay = dt.Day
        .wDayOfWeek = dt.DayOfWeek
        .wHour = dt.Hour + incHour
        .wMilliseconds = dt.Millisecond
        .wMinute = dt.Minute
        .wMonth = dt.Month
        .wSecond = dt.Second
        .wYear = dt.Year
    End With

    SetSystemTime.SetSystemTime(dateTimeStruct)
End Sub

我看到的行为是,在 2014-08-04 04:15:07,上面的方法 SetDateTime 以 dt 为 04/08/2014 04:15:07 如此有效地执行,时间设置但在现实,没有改变。我的日志显示,由于更改,PC 时钟跳到了 2014-08-04 05:15:07。 随后,在 2014-08-04 13:00:28(PC 时间 14:00:28)再次调用该方法并将时钟设置回 2014-08-04 13:00:28

什么可能导致这种行为。时区设置为伦敦,我们目前处于夏令时到 10 月。操作系统为 Win7 Embedded Standard。

有什么想法吗?

【问题讨论】:

这是您自己的代码导致 incHour 用法的怪异 - 为什么您不正确地将整个日期转换为 UTC,然后只使用它?此外,并非所有时区都与 UTC 有整小时的偏移,所以如果这是可移植的代码,它就会被破坏。 这段代码的目的是什么?你想做的相当于禁用“自动调整夏令时时钟”吗? Damien,我得到了整个小时的偏移量并将日期转换为 UTC,但它没有解释为什么代码在 13:00 而不是在 04:15 被塞住。数学几乎是一样的,不是吗?还是我缺少什么? 安德鲁,不,它是根据通过自定义协议接收的数据将电脑时钟与服务器同步。 PC 时钟仍应遵守夏令时。 @Sparers 如果您将 UTC 和 BST 放在您写作的时间上,这可能会有所帮助。当小时是 23 并且你加 1 时,我可以看到它出错了。也许你可以使用 SetLocalTime,其中的评论有一个有趣的点,即必须调用它两次。 【参考方案1】:

请改用SetLocalTime 函数,请注意其文档中的备注:

系统内部使用 UTC。因此,当您调用SetLocalTime 时,系统使用当前时区信息进行转换,包括夏令时设置。请注意,系统使用当前时间的夏令时设置,而不是您设置的新时间。因此,为确保结果正确,请再次调用 SetLocalTime,因为第一次调用已更新夏令时设置。

【讨论】:

以上是关于SetSystemTime kernel32 中的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Windows 10 IoT 中设置系统时间?

Qt设置系统时间(使用SetSystemTime API函数)

pywintypes.error: (1314, ‘****‘, ‘客户端没有所需的特权。‘)

引用kernel32.dll中的API来进行串口通讯

当 `OrdinalBase` 字段设置为 1 时,`kernel32.dll` 如何导出 0 的序数?

ptrace can't work in kernel 2.6.32 mips