0

在 .NET 中写了一些东西;它运作良好。现在我正在尝试使用 Win32 API 将其重写为 shell 扩展。最终我想将FILETIMEs 转换为 ISO-8601 字符串和从 ISO-8601 字符串转换。这是可行的,无需大惊小怪,使用GetTimeZoneInformationandFileTimeToSystemTimeSystemTimeToTzSpecificLocalTimeand将and结构StringCchPrintf的成员组装成一个字符串。SYSTEMTIMETIME_ZONE_INFORMATION

像往常一样使用日期/时间时,问题是夏令时。UsingGetTimeZoneInformation告诉我现在生效的 UTC 偏移量。使用 .NETDateTime.ToString("o")会考虑DateTime 中表示的时间的夏令时。

相同示例FILETIME
输出ToString("o"):2017-06-21T12:00:00.0000000-05:00
链式 API 的输出:2017-06-21T12:00:00-06:00

来自链式 API 调用的 UTC 偏移量是错误的。.NET 是如何DateTime做到的?我们如何在 Win32 中复制它?有没有类似的东西GetTimeZoneInformationForYear,但不是一年,而是本地时间的片刻?

4

1 回答 1

1

首先,我使用DYNAMIC_TIME_ZONE_INFORMATION结构和GetDynamicTimeZoneInformation

DYNAMIC_TIME_ZONE_INFORMATION并且TIME_ZONE_INFORMATION还有一个DaylightBias成员:

在夏令时发生的本地时间转换期间使用的偏差值。如果未提供 DaylightDate 成员的值,则忽略此成员。

该值被添加到偏差成员的值中,以形成夏令时使用的偏差。在大多数时区,该成员的值为 –60。

因此,如果日期是夏令时,则需要将其添加DaylightBiasBias. 另外,可以根据中的描述判断当前日期是否为夏令时DaylightDate

要选择月份中的正确日期,请将 wYear 成员设置为零,将 wHour 和 wMinute 成员设置为过渡时间,将 wDayOfWeek 成员设置为适当的工作日,并将 wDay 成员设置为在月(1 到 5,如果一周中的那一天没有出现 5 次,则 5 表示该月的最后一次出现)。

如果 wYear 成员不为零,则过渡日期为绝对日期;它只会发生一次。否则,它是每年发生的相对日期。

于 2021-02-08T05:55:04.650 回答