【问题标题】:Does TimeZoneInfo take DST into consideration?TimeZoneInfo 是否考虑夏令时?
【发布时间】:2012-07-03 19:25:26
【问题描述】:

在时区之间转换时,C# 是否考虑夏令时?

我有一个伦敦当前时间的源日期,我想将其转换为我的时区 (CET)。这是我正在使用的代码。

DateTime time = DateTime.ParseExact(timeString, "HH:mm", null);
time = DateTime.SpecifyKind(time, DateTimeKind.Unspecified);

//Convert it to the right timezone. It is currently in GMT

TimeZoneInfo gmt = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
TimeZoneInfo current = TimeZoneInfo.Local;

DateTime utc = TimeZoneInfo.ConvertTimeToUtc(time, gmt);
DateTime local = TimeZoneInfo.ConvertTimeFromUtc(utc, core.startTime = local;

目前运行良好。然而,当 DST 抬起丑陋的脑袋时,它会继续工作还是会严重崩溃?由于过去有很多问题,我对 TimeZones 有点警惕。

【问题讨论】:

  • 你知道伦敦不是格林威治标准时间,对吧?由于现在是北半球的夏天,伦敦是 UTC+1,而你是 UTC+2。
  • 看看我的问题是什么?我不想将其标记为 BST(这是当前时间),因为当它不再是 BST 时,它会返回到 GMT。我希望它是自动的。我讨厌时区。
  • 幸运的是,它会在夏季自动使用 BST,在冬季自动使用 GMT。你说得对,TimeZone 有问题,但这就是 TimeZoneInfo 的创建。
  • 一个问题是某些时区在 Windows 和 .net 中的名称真的很奇怪。例如 Europe/London 被误命名为 GMT Standard Time 并在夏季和冬季时间之间切换。但 GMT 没有,在 .net 中称为 Greenwich Standard Timestackoverflow.com/questions/2292334/…
  • 计时是一本完全该死的教科书,如果你想完全正确的话。微软甚至没有为以色列尝试,因为每年都有四十种左右的宗教 DST 变化(不能仅仅因为夏令时而在错误的时间庆祝,耶和华可能会让他的鼻子失去关节并开始打击!我无法理解像以色列这样精通技术的国家怎么会如此愚蠢,但事实就是如此。)GMT(格林威治标准时间)与 UTC(通用时间公约)几乎但不完全相同,与恒星时间几乎但不完全相同时间。这是混乱!

标签: c# timezone dst


【解决方案1】:

简短的回答是“并非无处不在,也不完美。”


TimeZoneInfo.GetAdjustmentRules 将为您提供有关 DST 偏移量更改以及它们何时生效和失效的规则集合。

但是,您的用户仍然可以通过取消选中 Windows 控制面板日期和时间中的“自动调整夏令时”来解决问题。如果在 Windows 中关闭了 DST,那么您将获得一个空的调整规则集合。

如果您想自动应用调整规则,您必须使用已设置 DateTimeKind 的 DateTime 对象。如果 DST 被关闭,这将在转换中得到遵守。

格林威治皇家天文台的格林威治标准时间是太阳时。英国人发明了从日期线偏移时区的整个业务,因为他们是第一个在全球范围内协调任何事情的人。在过去的平静日子里,他们拥有遍布全球的帆船海军,但没有无线电。订单滞后数周或数月,因此一致、精确的全球计时是唯一拥有比行星更大的参考系的人——皇家天文学家发明的。

月球的潮汐力正在减缓地球的自转。需要大量的果汁才能让海水上下晃动,这不是魔法,它来自地球的旋转时刻。

此外,太阳轨道的持续时间也不是恒定的,因此我们不时有闰秒,以使日历与行星现实同步。另一方面,恒星时没有这种愚蠢,所以我们远离它。然后是相对论漂移。 GPS 卫星的移动速度如此之快,以至于实际上必须补偿轻微的时间扭曲。

【讨论】:

  • 我是否正确理解为“不,您必须自己编写代码来检查它”?还是自动的?
  • 无论潮汐力使地球减速多少,这并不能准确回答问题:“TimeZoneInfo 是否考虑 DST?”答案实际上是:“是的,您不需要自己为此编写任何代码,至少在 .net 4.5 上”。
  • @pasx - 我在 2012 年 7 月写了这篇文章。4.5 是什么时候发布的? 2012 年 8 月。幸运的是,没有办法对愚蠢的 cmets 投反对票。
  • @PeterWone TimeZoneInfo 也在 2008 年发布的 3.5 中。有没有办法对 cme​​ts 的愚蠢答案投反对票? (:但老实说,我否决了您的回答,因为它给了我很多我不需要的信息,并且与使用 DST 转换相关的信息是错误的。没有可用于使用 DST 进行转换的代码。
  • 这个答案不是为你写的,它是为对计时复杂性感兴趣的人写的。如果附加信息对您没有用处,则说明其他人没有用。这可能会令人震惊,但并非所有互联网都是为了您的个人方便而创建的,您对 为什么 如此复杂的不感兴趣并不会降低信息对其他人的价值。我发现这说明了你宁愿贬低别人的贡献,而不是写一个有用的答案——你显然可以做的事情。
【解决方案2】:

至少在 .net 4.5 TimeZoneInfo 确实处理夏令时。

检查它的最简单方法是比较 BaseUtcOffset 和 GetUtcOffset

   var baseOffset = timeZoneInfo.BaseUtcOffset;
   var currentOffset = timeZoneInfo.GetUtcOffset(currentLocalTime);
   var isDst = currentOffset > baseOffset;
   var delta = currentOffset - baseOffset;

这比处理不需要的 AdjustmentRule 容易得多,如果您只对调整 DST 的 DateTime 感兴趣。

顺便说一句,GMT 已过时,取而代之的是 UTC。

【讨论】:

    【解决方案3】:

    在 .NET 中处理 1987 年之前的日期时要小心。 TimeZoneInfo 中您感兴趣的时区的默认 AdjustmentRules 可能不足以满足您的目的。在这里阅读更多:http://blog.appliedis.com/2013/03/06/beware-daylight-saving-time-transitions-in-dot-net/

    【讨论】:

      【解决方案4】:

      在时区之间转换时,C# 是否考虑夏令时?

      是的,假设您的计算机保持更新,因为有时区信息会随着 Windows 更新而更新。如果该国家/地区没有更改其 DST 时间段(最近发生在澳大利亚),即使没有 Windows 更新它也应该可以工作

      我有一个伦敦当前时间的源日期,我想将其转换为我的时区 (CET)

      你是什么意思'源日期是伦敦的当前时间'? 始终将您的日期存储为 UTC,并在“最后一分钟”将它们转换为所需的本地时间。

      如果您想知道夏令时更改时会发生什么,那么您可以通过更改计算机上的时钟来进行测试。

      【讨论】:

      • 这意味着我从一个给我伦敦时间的供应商那里获得了日期,我需要用供应商在我当地时区给我的另一个日期来规范它。我试图避免这些问题,但有时无事可做。我不想更改时钟来找出答案,因为我上次这样做时,由于某种原因(与构建时间有关),项目引用出现了很多问题。
      • @Aabela 这不是不更改计算机时钟的充分理由。你是你电脑的主人。更改时钟,测试,然后将其更改回来。您可以清理您的解决方案(在“构建”菜单下),这应该可以纠正。如果您仍然担心在虚拟机上测试它
      • 您应该将这两个时间都转换为 UTC 并在 UTC 中使用它们。
      猜你喜欢
      • 2011-08-14
      • 2018-09-19
      • 2013-09-22
      • 1970-01-01
      • 2014-02-22
      • 1970-01-01
      • 2018-01-01
      • 2011-10-25
      • 2020-09-12
      相关资源
      最近更新 更多