使用TimeZoneInfo.ConvertTime()的时间不正确

时间:2016-03-29 16:34:22

标签: c# datetime timezone

转换自:

后,我收到了意外的DateTime

(UTC) Dublin, Edinburgh, Lisbon, London(UTC-08:00) Baja California

以下是我一直在使用的代码。我希望serverDateTime29/03/2016 00:00:01( - 8小时),但我得到28/03/2016 23:00:01 - 这是一个9小时的差异。

    private static void Main(string[] args)
    {
        ReadOnlyCollection<TimeZoneInfo> timeZones = TimeZoneInfo.GetSystemTimeZones();
        TimeZoneInfo localTimeZone = timeZones.FirstOrDefault(tz => tz.DisplayName.Contains("London"));
        TimeZoneInfo serverTimeZone = timeZones.FirstOrDefault(tz => tz.DisplayName.Contains("California"));
        DateTime clientDateTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 29, 8, 0, 1);
        DateTime serverDateTime = TimeZoneInfo.ConvertTime(clientDateTime, localTimeZone, serverTimeZone);
    }

我的本​​地机器在英国,目前是UTC + 1,而Baja - California目前是UTC-7,所以我期望得到8小时的差异,而不是9.我做错了什么?

提前致谢。

1 个答案:

答案 0 :(得分:5)

一些事情:

  • "(UTC-08:00) Baja California"Baja California, Mexico - 不是美国加利福尼亚州。
  • 此区域条目遵循墨西哥DST规则doesn't start DST until April 3rd this year。因此,此条目仍然是UTC-8,解释了您观察到的时差。
  • 这个特殊条目在Windows中实际上是错误的,因为事实证明,整个巴哈加州的状态遵循美国夏令时的规则,而非墨西哥规则。

    • 2015年10月和11月,the tz mailing list archives对此进行了广泛的多线程讨论。这产生了相应的IANA区America/Santa_Isabel being deprecated with release 2016a。它现在链接到America/Tijuana,已经遵循美国DST规则。
    • Microsoft尚未对其数据进行类似的更改,但可能会在将来更新Windows时区数据。 (我已经将此情况告知了相应的人员。)与此同时,使用"(UTC-08:00) Pacific Time (US & Canada)" - 即使您正在谈论墨西哥下加利福尼亚州。
  • 请勿尝试按DisplayName查找时区。这些值将根据操作系统语言而有所不同。相反,请使用TimeZoneInfo.FindSystemTimeZoneByIdId属性未本地化。此外,Microsoft认为Id值是稳定标识符,因此它们不会随将来的更新而更改。 DisplayName值在过去已被修改,并且可能在将来确实发生变化。

    • 使用"GMT Standard Time"
    • 的ID "(UTC) Dublin, Edinburgh, Lisbon, London"
    • 使用"Pacific Standard Time"
    • 的ID "(UTC-08:00) Pacific Time (US & Canada)"
    • ID "Pacific Standard Time (Mexico)"适用于"(UTC-08:00) Baja California" - 但由于我所描述的原因,请勿使用此条目。
  • 真的,你根本不应该关心服务器上的时区。服务器应该只关注UTC。 (请注意,伦敦不是UTC,因为它在夏天切换为BST)

  • 我不确定你对这条线的意图是什么:

    DateTime clientDateTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 29, 8, 0, 1);
    

    DateTime.Now拉出月份和年份将使用服务器的时区。然后,您将29的固定日期与8:00:01的固定时间结合使用。这将在非闰年的2月份失败(当月只有28天),并且当服务器的日期与客户的日期和年份不同时,也可能会给出错误的日期。 ; s(例如接近从一个月到另一个月的过渡)。