夏令时是否启用?

3
在Windows 7中的时区设置中,您可以启用或禁用“自动调整夏令时时钟”。如果禁用该功能,则计算机时钟将始终显示标准时间,即使时区设置为遵循夏令时的时区。
这个问题询问DST是否启用,但答案只是说明当前日期/时间是否在DST规则内,因此应进行调整,但操作系统的设置表示要保持标准时区的时间。
如何从C#获取“自动调整夏令时时钟”?

1
在那个问题中,还有另一个答案展示了如何从注册表中获取设置。这有什么问题吗?我从未听说过有托管 API 可以做到这一点。 - Marcel N.
https://dev59.com/anM_5IYBdhLWcg3wvFzJ 也涉及到相同的问题。 - C.Evenhuis
Marvel N. - 从C#访问注册表可以吗?如果这是唯一的解决方案,我会尝试的,但我不想动注册表。每次我尝试使用“只需去注册表中的此键”来进行的任何黑客都从未奏效过。 - Robert Deml
@C.Evenhuis - 不,它不是。完全不一样。 - Matt Johnson-Pint
@MattJohnson 你说得对,当我发布这个帖子时,我认为排除 CultureInfo 作为可能性会有所帮助,我的错。 - C.Evenhuis
1个回答

3
如果您只想知道本地时区是否支持DST,请使用以下代码:
bool hasDST = TimeZoneInfo.Local.SupportsDaylightSavingTime;

在以下任何一种情况下,这个语句均为false:
  • 所选时区不使用夏令时(如亚利桑那州和夏威夷)。

  • 所选时区使用夏令时,但用户已清除“自动调整夏令时时钟”复选框。

如果您特别想知道用户是否禁用了通常支持它的时区的夏令时,则应这样做:

bool actuallyHasDST = TimeZoneInfo.Local.SupportsDaylightSavingTime;
bool usuallyHasDST = TimeZoneInfo.FindSystemTimeZoneById(TimeZoneInfo.Local.Id)
                                 .SupportsDaylightSavingTime;
bool dstDisabled = usuallyHasDST && !actuallyHasDST;

dstDisabled 变量仅在用户明确取消“自动调整夏令时”复选框时为 true。如果该区域不支持 DST,因此该框不存在,则 dstDisabled 为 false。

这是如何工作的?

  • Windows stores the chosen time zone settings in the registry at:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation
    
  • The DynamicDaylightTimeDisabled key is set to 1 when the box is cleared. Otherwise it is set to 0.

    One of the answers in the other question you mentioned specifically checked for this value, which is also an acceptable solution.

  • Calling TimeZoneInfo.Local takes into account all of the information in that key.

  • Looking up the time zone by the Id does not take into account any of the information in the registry, other than the Id itself, which is stored in the TimeZoneKeyName value.

  • By comparing the registry-created information against the looked-up information, you can determine whether DST has been disabled.

请注意,这也在MSDN文档中有详细说明TimeZoneInfo.Local的备注部分。

我注意到的一件事是,如果在程序运行时更改了设置,则 TimeZoneInfo.Local.SupportsDaylightSavingTime 不会更改,因此必须进行缓存。使用注册表将获得最新的信息。也可以通过 WMI 获取此信息。 - Mike Zboray
@mikez - 正确。如果你担心这个问题,你需要在检查TimeZoneInfo.Local之前调用TimeZoneInfo.ClearCachedData()。注册表检查是最直接的方法。如果您能将WMI示例发布为答案,我会很高兴看到它 :)。 - Matt Johnson-Pint

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接