我'm trying to implement correct DST adjustment handling in my alarm clock app. So I'读取DYNAMIC_TIME_ZONE_INFORMATION的描述,用于通过GetTimeZoneInformationForYear API检索当前的DST调整信息,并说明如下:
DaylightDate:SYSTEMTIME结构,包含在此操作系统上从标准时间转换为夏令时的日期和本地时间 . 如果时区不支持夏令时或者调用者需要禁用夏令时,则SYSTEMTIME结构中的wMonth成员必须为零 . 如果指定了此日期,则还必须指定此结构中的StandardDate成员 . 否则,系统会假定时区数据无效,并且不会应用任何更改 . 要选择月中的正确日期,请将wYear成员设置为零,将wHour和wMinute成员设置为过渡时间,将wDayOfWeek成员设置为相应的工作日,并将wDay成员指示为该周内某一天的发生日期 . 月份(1到5,其中5表示如果一周中的那一天没有发生5次,则在月份中最后一次出现) . 如果wYear成员不为零,则过渡日期是绝对的;它只会发生一次 . 否则,它是每年发生的相对日期 .
我也在检查世界各地观察到的current DST adjustments,如果相对DST调整看起来非常简单,我不清楚如何通过DYNAMIC_TIME_ZONE_INFORMATION传达以下调整 - 只有一个绝对的月份和一天 .
例如:
Egypt
-----
DST Start: May 15
DST End: Last Friday September
或者这个:
Iran
----
DST Start: March 21–22
DST End: September 21–22
有谁知道如何做到这一点?
2 回答
要了解时区结构,有助于在以下键下查看Windows注册表:
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\
在这里,您将找到the Microsoft time zone database的所有内置时区,即maintained by Microsoft via Windows Updates .
让我们看一下您提到的示例案例之一:
.\Egypt Standard Time\
.\Egypt Standard Time\Dynamic DST\
由此可以看出,2005 - 2011年定义了特定的DST规则 . 在此范围之外,我们回退到根条目的
TZI
值 .你_1613444_因为埃及几乎没有注意到the upcoming change . 您可以预期很快就会有Microsoft提供的修补程序随更新一起提供 .
注册表中的二进制数据被反序列化为
REG_TZI_FORMAT
结构,如下所示:您应该注意的一个问题是Windows不喜欢在午夜过渡的时区 . 解决方法是,不必说"00:00 on the last Friday in September",而是在9月的最后一个星期四说“23:59:59.999” . 但是,在这里你必须要小心,因为像这样的规则有时会导致错误的派生日期 . 为了解决这个问题,有时每年都会有自己的规则 . 仍然使用重复模式格式而不是固定日期格式,主要是出于一致性目的 .
但是,还有另一个问题 - 这种结构只能支持一年中两个夏令时的转换 . 当DST开始时,一个在
DaylightDate
,当DST结束时,一个在StandardDate
. 由于埃及除了斋月之外正在制定夏令时,所以会有four transitions . 这也发生在Egypt in 2010,也经常发生在Morocco . 为了解决这个设计缺陷,微软传统上发布了多个更新,时间恰好与变化相吻合 . (例如,请参阅KB2297272 . )我假设微软将推出多次更新,所以为了举个例子,我们将省略斋月期 . 该规则在5月的第2个星期三23:59:59.999开始DST,并在9月的最后一个星期四23:59:59.999结束 .
这对应于具有这些值的
REG_TZI_FORMAT
结构(为清晰起见,为JSON):我认为这个答案足够长,所以如果你愿意,我会留给你推断伊朗的规则 . 不过,我要指出,伊朗的Windows数据自2009年以来一直不正确,尚未收到更新 . : - /
作为旁注,如果要指定固定日期规则,则可以提供非零"real"年值 . 然后,day字段表示实际的日期 - 而不是发生的日期 . 但是,通常会避免这种情况,因为它仅对适用于各个年份的动态DST规则有意义 . 在根节点中的泛型
TZI
条目中使用固定日期是没有意义的 .UPDATE
Microsoft已于KB2967990发布了2014年埃及的更新 .
伊朗是一个奇怪的国家DST转换日期不符合Microsoft注册表所期望的常规规则 . 例如:三月的第二个星期天 . 所以我同意您需要使用绝对日期,但使用注册表格式 . DST过渡日期的工作日几乎每年都有所不同 .
伊朗DST过渡日期基于波斯日历https://mm.icann.org/pipermail/tz/2003-March/012053.html
所以动态注册表方法将是每一年都有很多变化的答案!