我一直在尝试在.net4中使用TimeZoneInfo.GetSystemTimeZones来替换使用COM调用某些MFC代码的旧方法。但是,我不得不恢复到COM方法,因为GetSystemTimeZones不会返回所有时区。在我们的英国,并且在我们的选项列表中不包括GMT标准时间是一个问题。
当我查看注册表时,我发现 GMT标准时间有一个 Dynamic DST 子项,没有定义规则。我下载了.net4源代码,在TimeZoneInfo.cs中,GetSystemTimeZones最终调用TryCreateAdjustmentRules,如果 Dynamic DST 键没有定义FirstEntry或LastEntry,它似乎返回false。
//
// loop over all of the "<time_zone_name>\Dynamic DST" hive entries
//
// read FirstEntry {MinValue - (year1, 12, 31)}
// read MiddleEntry {(yearN, 1, 1) - (yearN, 12, 31)}
// read LastEntry {(yearN, 1, 1) - MaxValue }
// read the FirstEntry and LastEntry key values (ex: "1980", "2038")
Int32 first = (Int32)dynamicKey.GetValue(c_firstEntryValue, -1, RegistryValueOptions.None);
Int32 last = (Int32)dynamicKey.GetValue(c_lastEntryValue, -1, RegistryValueOptions.None);
if (first == -1 || last == -1 || first > last) {
rules = null;
return false;
}
当TryCreateAdjustmentRules返回false时,TryGetTimeZoneByRegistryKey会抛出InvalidTimeZoneException,这意味着 GMT标准时间不会添加到时区集合中。我已经尝试删除空的 Dynamic DST 子项,但有些东西又将它们重新添加(可能是Windows Update)。
我做了很多搜索,但没有看到其他人报告此问题。我不确定是否存在GetSystemTimeZones修复,或者我是否可以停止首先出现的空 Dynamic DST 子项。有什么想法吗?
答案 0 :(得分:1)
我猜这只是一个注册问题。
此处概述了类似于WinXP / Server 2003 SP1的内容。 请查看以下内容是否有帮助: http://blogs.technet.com/b/dst2007/archive/2007/03/06/missing-time-zones-in-registry.aspx
我的猜测是你可以从另一台机器导出整个注册表项,然后将它应用到你有问题的盒子里。
答案 1 :(得分:1)
事实证明,问题出在我们的COM对象上,而不是.NET代码。读取注册表的代码应该只是读取,但它错误地调用RegCreateKey来优化对同一注册表分支的多个调用。
当COM对象因新版本注册(具有管理员权限)时,它会加载时区并为本地时区创建 Dynamic DST ,在我的情况下为GMT / UTC。
管理员,我想这个问题应该标记为删除。
答案 2 :(得分:0)
在查看您的问题后,甚至运行您在评论中提供的代码打印出时区列表,我无法让GMT显示在我的系统上。我正在运行Windows 7 Professional并且选择GMT不是一个选项。我知道这并不能解决你的问题而且你 - 就像很多其他人一样 - 听起来你真的需要让它与GMT合作。
但是,如果可能的话,如果您看到使用UTC的方法,那么我会查看这些链接:
Windows 7 Lack of Support for GMT
您问题的另一个可能的答案是,无论如何您可以创建一个围绕UTC值的包装来显示GMT吗?我问,因为这个问题似乎不会很快消失。即使你现在让它工作 - 将来它可能再次破裂。如果我想出一个方法,我会更新我的答案。