【问题标题】:GetSystemTimeZones missing GMT Standard TimeGetSystemTimeZones 缺少 GMT 标准时间
【发布时间】:2012-03-27 01:04:07
【问题描述】:

我一直在尝试使用 .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 更新)。

我进行了很多搜索,但没有看到其他人报告此问题。我不确定是否有 GetSystemTimeZones 修复,或者我是否可以停止首先出现的空 Dynamic DST 子键。有什么想法吗?

【问题讨论】:

  • 这太奇怪了——我肯定会返回“GMT 标准时间”。你能发布你用来确定它丢失的代码吗?可能没问题,但我们看到了奇怪的结果......
  • 我不想这么说,但它适用于我的系统,我在英国,我在返回的 101 个值中看到 GMT Standard Time。你在另一个系统上试过这个吗?
  • 乔恩,您的 GMT 标准时间注册表项是否有一个空的动态 DST 子项?
  • @RichardHawkins:我应该查看的注册表项到底在哪里? (您是否出于兴趣在其他机器上查看了注册表项是否相同?)
  • @RichardHawkins:好的。好吧,听起来您需要深入了解为什么您有一个空的动态 DST 子项...可能通过 regmon? (系统内部)

标签: c# .net windows timezone


【解决方案1】:

我猜这只是一个注册表问题。

此处为 WinXP / Server 2003 SP1 概述了类似的内容。 请查看以下内容是否有帮助: http://blogs.technet.com/b/dst2007/archive/2007/03/06/missing-time-zones-in-registry.aspx

我的猜测是您可以从另一台机器导出整个注册表项,并将其应用于有问题的盒子。

【讨论】:

  • 我的问题是我可以通过在注册表编辑器中删除 Dynamic DST 子项来摆脱它,并且注册表看起来没问题。稍后,密钥会重新出现,但这可能是几天后。我只是不知道是什么导致它再次出现。我将尝试在测试服务器上使用 regmon 看看是否能提供任何线索。
【解决方案2】:

在查看了您的问题,甚至运行您在 cmets 中提供的代码以打印出时区列表后,我无法让 GMT 显示在我的系统上。我正在运行 Windows 7 Professional,但不能选择 GMT。我知道这并不能解决您的问题,而且您 - 和许多其他人一样 - 听起来您确实需要让它与 GMT 一起使用。

但是,如果可能的话,如果您看到使用 UTC 的方法,那么我会查看以下链接:

Windows 7 Lack of Support for GMT

Converting UTC to GMT

您的问题的另一个可能答案是,您是否可以围绕 UTC 值创建一个包装器以显示 GMT?我问是因为这个问题似乎不会很快消失。即使你现在让它工作 - 将来它可能会再次崩溃。如果我想出一个方法,我会更新我的答案。

【讨论】:

  • 感谢您的回复,但让我澄清一下。注册表中的键是 GMT Standard Time(英国时区),但时区列表中的显示文本是 (UTC) Dublin, Edinburgh, Lisbon, London . UTC 和 GMT 是同一事物的两个名称,Windows 2003 显示 GMT 而 2008 显示 UTC。
  • 这是一个很长的镜头,但是您是否尝试过取消注册您的 COM 对象以查看是否会阻止密钥显示备份?
  • 我需要我的 COM 对象来实现其他功能。据我所知,它只从这个注册表分支读取。我现在让进程监视器查看注册表以尝试记录谁重新创建了它。
【解决方案3】:

事实证明,问题出在我们的 COM 对象上,而不是 .NET 代码上。读取注册表的代码应该只是读取,但它错误地调用了RegCreateKey来优化对同一个注册表分支的多次调用。

当 COM 对象因新版本而注册(具有管理员权限)时,它会加载时区并为本地时区创建 动态 DST,在我的例子中是 GMT/UTC。

管理员,我想这个问题应该被标记为删除。

【讨论】:

  • 啊哈!所以它是 COM 对象! :D
猜你喜欢
  • 2010-12-24
  • 2011-01-06
  • 1970-01-01
  • 1970-01-01
  • 2011-01-18
  • 2016-02-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多