代码之家  ›  专栏  ›  技术社区  ›  Shahin Dohan

调整中的“夏令时”(DST)选项。NET,就像Windows一样

  •  2
  • Shahin Dohan  · 技术社区  · 7 年前

    我正在尝试复制Windows日期(&m);UWP应用程序中的时间设置,我在处理夏令时(DST)设置时遇到了麻烦。

    我设法让一切正常工作,我可以通过我的应用程序更改系统时间和时区,但是 自动调整夏令时 让我困惑。

    起初,我认为这足够检查一下 TimeZoneInfo.SupportsDaylightSavingTime ,然后我发现我可能还需要通过执行以下操作来检查当前选择的日期/时间是否在DST范围内 TimeZoneInfo.IsDaylightSavingTime .

    嗯,我认为我是对的,但经过测试,我自己的“调整DST”选项与Windows设置不同,而且由于我看不到Windows源代码,我不知道他们正在检查哪些其他条件来禁用/启用它。

    我的UWP应用程序:

    Date & Time settings in my UWP app

    Windows设置:

    Windows Date & Time settings

    我还缺什么吗?我的另一个问题是 here 对于那些感兴趣的人。

    也许一些掌握内幕信息的微软开发人员可以告诉我这个切换开关背后的逻辑:-)

    提前谢谢!

    更新时间:

    结果来自 tzutil 显示日期为2011年5月16日且时区为莫斯科(UTC+3)时,使用命令关闭DST tzutil /s "Russian Standard Time_dstoff" 只返回“俄罗斯标准时间”,不带\u dstoff,因为DST不适用,这与Windows报告一致。

    但是,为什么呢。NET的TimeZoneInfo类这么说? .NET says current datetime is in DST range 还尝试了:

    var currentDateTime = new DateTime(2011, 5, 16, 0, 0, 0, DateTimeKind.Local);
    var isDst = TimeZoneInfo.Local.IsDaylightSavingTime(currentDateTime); //True
    

    所以NET表示当前日期在DST范围内,但无法使用TZUTIL或从Windows设置关闭DST?

    也许我错过了一些很明显的东西,但我看不到。。。

    更新时间:

    将月份更改为2月,根据调整规则在Windows中打开调整DST切换?但是,在赫尔辛基,我们也有这些转换,并且切换没有被禁用?有什么不同?

    更新时间:

    决定不做这些,只是检查一下 TimeZoneInfo。SupportsDaylightSavingTime支持 .不值得任何人花时间或精力像Windows那样做。

    1 回复  |  直到 6 年前
        1
  •  3
  •   Matt Johnson-Pint    7 年前

    解决您的问题需要做以下几件事:

    • 不要使用 System.TimeZone 课堂上——永远。它有很多问题,还有更好的选择。对大多数人来说。NET代码,使用 System.TimeZoneInfo 相反既然您说您正在编写一个UWP应用程序,那么您还可以从 Windows.Globalization.Calendar Windows.Globalization.DateTimeFormatting.DateTimeFormatter 上课。开源库,如 Noda Time 也可以是一个不错的选择。

      在显示的第一个代码块中,您正在使用 System.TimeZone.IsDaylightSavingTime .文件中的备注解释了您看到的结果:

      “因为 TimeZone 类支持单个夏令时调整规则 IsDaylightSavingTime(DateTime) 方法将当前调整规则应用于任何日期,无论调整规则是否在该日期生效。假设操作系统本身具有准确的历史夏令时数据,则可以使用 TimeZoneInfo.IsDaylightSavingTime 方法尽可能使用 TimeZoneInfo。IsDaylightSavingTime 方法"

    • 在显示的第二个代码块中,您正确地使用了 System.TimeZoneInfo.IsDaylightSavingTime 而且正在变得 True 当你期望的时候 False .虽然这令人困惑,也可能是不正确的,但可以解释:

      • 2011年,莫斯科在UTC+3开始日历年。然后在3月27日凌晨2:00将其偏移量更改为UTC+4( reference here ).这是 标准时间 ,而不是与DST相关的更改。
      • Windows中的数据结构( TIME_ZONE_INFORMATION ,则, DYNAMIC_TIME_ZONE_INFORMATION ,更具体地说, REG_TZI_FORMAT )不支持在日历年中更改标准偏移量。很久以前,它们的设计就没有这种改变。
      • 为了适应当地时间的变化 建模 在Windows中,作为DST更改,DST周期从3月27日凌晨2:00开始,一直持续到年底。这样可以在转换过程中保持本地时间的准确性,但代价是从声明或推断其结果与DST明确相关的API返回不准确的信息(例如 系统TimeZoneInfo。IsDaylightSavingTime ).
      • 因此,可以考虑这样的方法,即告诉您某个时段的本地时间与UTC的偏移量是否高于一年中其他时间的偏移量。这可能与夏令时有关,也可能与标准时间的变化有关。
    • 据我所知,Windows确实会查看这些数据来确定是否显示该选项。如果当前日历年中存在过渡(由系统时钟确定),则将显示该选项-无论该过渡是否与DST相关或由于其他原因。

    此外,一些一般建议:

    • 大多数应用程序应该 正在尝试更改系统时间、时区或DST设置。尽管确实有办法做到这一点,但它可能会产生严重后果。这些是 系统范围 全局设置,它将影响计算机上的所有内容,而不仅仅是应用程序。

      特别是 时间 过大可能会影响与其他系统进行正确身份验证的能力。例如,Windows身份验证(Active Directory、SSPI等)使用Kerberos,Kerberos与UTC之间有5分钟的容差。此外,根据系统时钟,如果证书过期或尚未颁发,访问使用安全证书(HTTPS、SSL、TLS等)的网站可能会失败。因此,成功的最安全途径是自动设置时间,并且不允许用户偏离。

      虽然更改时区和/或DST设置不会影响身份验证,但它仍然是一个全局设置。计算机上使用本地时间的任何位置都将使用此设置,而不仅仅是您的应用程序。

    • 如果确实要更改时区,请记住,您可能需要清除本地时区缓存以获取应用程序中的新设置。 See this question and answer for more details .

    • 如果您的目的只是更改应用程序的时区,那么只需跟踪 TimeZoneInfo.Id 并通过 TimeZoneInfo.ConvertTime 以及必要的相关方法。

    • 你可能会 需要设置以禁用自动DST调整。Windows中存在的此设置是早期WinNT和Win9x中时区设置的原始实现的遗留工件。大多数用户应该保持打开状态。

      如今,关闭它只有一个合法的使用案例,即政府宣布将时区从有DST的时区更改为没有DST的时区(或有“永久DST”) 没有DST时,没有其他具有相同基准偏移量的现有时区条目 当上述政府没有提供足够的时间让微软在更改生效之前为受影响地区创建和分发新的时区条目时。这样的事情确实发生过,但很少见。嗯,这种设置在将来某个时候消失是合理的。(这只是我个人的观点,不是代表微软。)