【问题标题】:Handling DST in 24H Application在 24H 应用程序中处理 DST
【发布时间】:2010-10-31 18:10:27
【问题描述】:

我正在开发一个需要每天 24 小时运行的应用程序,并且正在努力正确实现对 DST 的支持。目前所有时间都以 UTC 格式存储,但是当我尝试以本地时间显示时遇到问题。现在我正在使用savedDate.ToLocalTime() 将数据库值转换为本地时间以进行显示。这似乎工作正常,除了当我更改时区信息以测试 DST 时。如果我修改客户端 PC 上的时区,则显示不会更新为新时区。是否有更好的方法来测试 DST,或者我的本地时间转换在这种情况下不正确?

【问题讨论】:

  • 我想我可能会对下面的回答造成混淆。这是紧凑的框架,还是没有?在我们讨论的过程中,您使用的是哪个版本的 .NET Framework?
  • 我使用的是 .NET 2.0,而不是 Compact Framework。

标签: c# .net timezone


【解决方案1】:

我记得读过,也许是关于 Compact Framework,在报告 DST 时,.NET 并不是最可靠的。更可靠的是获取本地时间和 UTC 的当前时间,然后自己确定(并在未来的调整中使用)差异。如果不是真的有必要,那似乎是一条可怕的路线。我会看看我是否能找到一个参考来支持我认为我记得的内容。

您究竟在做什么来更改工作站上的时区?

【讨论】:

  • 我将系统时钟上的时区从东部时间更改为大西洋时间。这是为了通过保持本地盒子的 UTC 时间相同来测试 DST,但要更改本地时间。
  • TimeZone.CurrentTimeZone.ToLocalTime(savedDate) 是否给出不同的结果 (stackoverflow.com/questions/179940/…)?
  • "是的,当前时区已缓存。您必须调用 System.Globalization.CultureInfo.ClearCachedData() 来重置它。" (stackoverflow.com/questions/296918/…) -- 也许这有帮助?
  • 这是有用的信息 - 您是否知道 DST 在实际发生更改时是否可以解决这个问题?
  • 解决这个问题?我不关注。
【解决方案2】:

嗯。您是否希望实际上在应用运行时更改时区?如果框架在第一次获取它之后缓存它,我不会感到惊讶。

我会在设备上设置时区,将时间更改为“就在更改为 DST 之前”,运行应用程序并检查它是否正确报告时间。然后将时间更改为“就在夏令时更改之前”。

请记住,根据您的设备及其时区数据库的使用年限,它可能不知道几年前美国 DST 的变化。 (啊,时区。我爱他们。)

【讨论】:

  • 好吧,问题不一定是在应用程序运行时更改时区,这只是我尝试测试 DST 的方法(有没有更好的方法?)。但由于某种原因,它似乎被缓存了,所以当我使用 ToLocalTime 时,它​​仍在从旧时区提取时间。
  • 我的意思是,如果更改时区不是您在现实生活中需要担心的事情,但它会扰乱您的测试,那么请不要在测试中这样做 :) 我知道停止应用程序,更改设置,重新启动它,等待一个半小时(所以你会经历完整的过渡期)然后再次更改它等等,但我怀疑它是一个痛苦'将比摆弄代码以避免缓存问题更容易。当然可能会有一个简单的解决方案即将发布:)
  • 我同意停止应用程序并重新加载以获取正确的时间很容易,但这对于此应用程序来说是不可行的。不幸的是,它需要通过 DST。
  • 我想你误解了我的意思。当我说“时区”时,我的意思是“欧洲/伦敦”之类的东西,冬天是 UTC,夏天是 UTC+1。你就这样离开它,DST 就会自动更改。时区本身不会因为与 UTC 的当前偏移量而改变:)
  • 对,我知道夏令时更改时时区不会更改。我只是不确定 ToLocalTime 是否会考虑到这一点。感谢您提供测试方案,出于某种原因,我没有想到这一点。 :)
【解决方案3】:

如果您从数据库中检索 DateTime 值,您通常会获得一个 DateTime,其 Kind 属性设置为 DateTimeKind.Unspecified。基本上是因为我知道的任何特定于数据库的 DateTime 类型(例如 SqlDateTime)都不包含时区信息。

如果您随后尝试使用 savedDate.ToLocalTime() 将其“转换”为本地时间,您将获得与存储相同的 DateTime 值,无需任何转换。

您需要做的是在执行转换之前表明保存的日期是UTC,例如:

DateTime savedDateTime = (DateTime) reader["SomeDateTimeColumn"];

// Convert from unspecified to UTC
DateTime utcDateTime = savedDateTime.SpecifyKind(savedDateTime, DateTimeKind.Utc);
...
// Convert from UTC to local
DateTime localDateTime = utcDateTime.ToLocalTime();

【讨论】:

    【解决方案4】:

    我发现一些 .Net CF 2.0 版本不能正确地在 UTC 和本地时间之间进行时间转换。这些问题围绕着几年前美国时区发生的变化。

    症状是 DST 似乎直到 4 月(旧规则)而不是 3 月(新规则)才被视为生效。想必也是DST变更(10月/11月)后端也有问题。

    到目前为止,我还没有找到有关翻译正常工作所需的最低构建的信息。

    请注意,这不是通过应用操作系统 DST 修复程序来解决的(显然,也应该安装它)。据我所知,它完全是 CF 固有的。我没有尝试过所有组合,但请小心。

    如果您想在 CF 中进行准确的翻译,您只有两个选择:

    1. 自己进行转换(非常复杂、僵化且容易出错)。

    2. 确保您在设备上安装了必要的 .Net 和 OS 补丁,以确保翻译准确。

    您也许还可以找到适合您的类库。一个有希望的类是World Clock / Code Project),但不幸的是,它依赖于 CF 中不可用的注册表信息。因此,它不能直接移植到 CF。

    最后,任何自行推出的解决方案都需要提供可用的时区信息(UTC 偏移量、DST 开/关日期等)。并且始终准确。

    很抱歉带来坏消息。

    【讨论】:

      猜你喜欢
      • 2013-02-09
      • 2018-08-05
      • 2016-02-19
      • 2014-10-01
      • 2011-01-27
      • 2011-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多