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

nf3*_*743 1 c# timezone datetime

从转换时我得到一个意外的DateTime:

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

以下是我一直在使用的代码.我期待serverDateTime成为29/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);
    }
Run Code Online (Sandbox Code Playgroud)

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

提前致谢.

Mat*_*int 5

一些东西:

  • "(UTC-08:00) Baja California"墨西哥下加利福尼亚州 - 不是美国加利福尼亚州.
  • 此区域条目遵循墨西哥DST规则,该规则直到今年4月3日才开始DST.因此,此条目仍然是UTC-8,解释了您观察到的时差.
  • 这个特殊条目在Windows中实际上是错误的,因为事实证明,整个下加利福尼亚州遵循美国夏令时的规则,而非墨西哥规则.

    • 2015年10月和11月,在tz邮件列表档案中对此进行了广泛的多线程讨论.这导致相应的IANA区域America/Santa_Isabel 在2016a版本中被弃用.它现在链接到America/Tijuana,已经遵循美国DST规则.
    • 微软尚未对其数据进行类似的更改,但可能会在未来更新Windows时区数据.(我已经将此情况告知了相应的人员.)与此同时,"(UTC-08:00) Pacific Time (US & Canada)"即使您正在谈论墨西哥下加利福尼亚州,也要使用它.
  • 不要试图通过它来查找时区DisplayName.这些值将根据操作系统语言而有所不同.相反,使用TimeZoneInfo.FindSystemTimeZoneById.该Id属性没有本地化.此外,Microsoft认为这些Id值是稳定的标识符,因此它们不会随着将来的更新而更改.DisplayName过去曾对这些价值进行了修改,未来可能会发生变化.

    • 使用ID "GMT Standard Time""(UTC) Dublin, Edinburgh, Lisbon, London"
    • 使用ID "Pacific Standard Time""(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);
    
    Run Code Online (Sandbox Code Playgroud)

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