我的问题是我是否需要确保我的代码与使用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_INFORMATION
和TIME_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);
}
}
}