是否有时区正确地使用了TimeZoneInfo IsFixedDateRule ?



我的问题是我是否需要确保我的代码与使用IsFixedDateRule属性的时区一起工作?似乎使用此规则的时区都没有实际指定转换日期。

我正在编写一些单元测试来测试一些实用程序函数,这些函数使用来自Microsoft TimeZoneInfo库的时区信息。

根据他们的IsFixedDateRule的文档在这个链接:https://msdn.microsoft.com/en-us/library/system.timezoneinfo.transitiontime.isfixeddaterule (v = vs.110) . aspx如果IsFixedDateRule为true,则从TransitionTime属性Day, Month和TimeOfDay中获得夏令时转换的日期。

然而,我已经枚举了整个集合,却找不到任何使用这些属性的时区。虽然有些时区(例如委内瑞拉标准时间,古巴标准时间)确实有IsFixedDateRule=true,但在所有这些情况下,过渡时间总是1月1日午夜。

下面是一些示例代码来演示这个问题。这个测试通过了,但根据上面的链接文章,它不应该通过。

    [Test]
    public void TemporaryDSTMuckaroundTest()
    {
        var timeZones = TimeZoneInfo.GetSystemTimeZones();
        foreach (var timeZoneInfo in timeZones)
        {
            var f = timeZoneInfo.StandardName;
            foreach (var adjustmentRule in timeZoneInfo.GetAdjustmentRules())
            {
                var a = adjustmentRule.DaylightTransitionStart.IsFixedDateRule;
                if (a)
                {
                    var start = adjustmentRule.DaylightTransitionStart;
                    var end = adjustmentRule.DaylightTransitionEnd;
                    Assert.IsTrue(start.Month == 1);
                    Assert.IsTrue(end.Month == 1);
                    Assert.IsTrue(start.Day == 1);
                    Assert.IsTrue(end.Day == 1);
                    Assert.IsTrue(start.TimeOfDay.Hour == 0);
                    Assert.IsTrue(end.TimeOfDay.Hour == 0);
                }
            }
        }
    }

实际的夏时制转换很少在年份边界。您可能会在数据中看到这些,因为Windows模型在注册表中每年都在变化,有时有必要将一年的模型与下一年的模型不同。

例如,考虑一个没有夏令时的时区,但在年中经历了一个标准的偏移量变化。这可以建模为夏令时从年初到年中,或从年中到年底的过渡-取决于偏移量是增加还是减少。

IsFixedDateRule属性而言,它直接映射到Win32 API中DYNAMIC_TIME_ZONE_INFORMATIONTIME_ZONE_INFORMATION结构所使用的SYSTEMTIME结构的wYear字段,以及与Windows注册表中的二进制数据匹配的底层REG_TZI_FORMAT结构。文档状态:

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

所以- Windows API支持这个,因此TimeZoneInfo类也支持。是否有实际的数据填充在当前发布的Windows时区数据版本中是无关紧要的。

请记住DateStart和DateEnd属性。转换时间不总是在1。1月。这也取决于年份。例如,政府可以改变夏令时的日期。这也是一个时区可以有多个调整规则的原因:MSDN

[Test]
    public void TemporaryDSTMuckaroundAdaptedTest()
    {
        var timeZones = TimeZoneInfo.GetSystemTimeZones();
        foreach (var timeZoneInfo in timeZones)
        {
            var name = timeZoneInfo.StandardName;
            foreach (var adjustmentRule in timeZoneInfo.GetAdjustmentRules())
            {
                var startFixed = adjustmentRule.DaylightTransitionStart.IsFixedDateRule;
                if (startFixed)
                {
                    Console.WriteLine(name);
                    Console.WriteLine(adjustmentRule.DateStart);
                    var start = adjustmentRule.DaylightTransitionStart;
                    Assert.IsTrue(start.Month == 1);
                    Assert.IsTrue(start.Day == 1);
                    Assert.IsTrue(start.TimeOfDay.Hour == 0);
                }
                var endFixed = adjustmentRule.DaylightTransitionEnd.IsFixedDateRule;
                if (!endFixed)
                    continue;
                Console.WriteLine(adjustmentRule.DateEnd);
                var end = adjustmentRule.DaylightTransitionEnd;
                Assert.IsTrue(end.Month == 1);
                Assert.IsTrue(end.Day == 1);
                Assert.IsTrue(end.TimeOfDay.Hour == 0);
            }
        }
    }

相关内容

  • 没有找到相关文章

最新更新