根据夏令时将日期时间(本地或 utc)转换为莫斯科和基辅时区问题

Converting datetime (local or utc) to Moscow and Kiev timezone issues depending on DayLight saving time

有一些时区可以切换到夏令时,也可以不切换。我知道俄罗斯不会切换到这个时间,乌克兰切换到夏令时。

据我所知link .NET TimeZoneInfo from Olson time zone莫斯科使用俄罗斯标准时间而基辅(乌克兰)使用 FLE 标准时间。

我的测试是:

  1. 冬天,俄罗斯,DateTimeKind.Utc

  2. 冬天,俄罗斯,DateTimeKind.Local

  3. 夏天,俄罗斯,DateTimeKind.Utc

  4. 夏天,俄罗斯,DateTimeKind.Local

  5. 冬天,基辅,DateTimeKind.Utc

  6. 冬天,基辅,DateTimeKind.Local

  7. 夏天,基辅,DateTimeKind.Utc

  8. 夏天,基辅,DateTimeKind.Local

我的电脑时间是 (UTC+00:00) 伦敦 +1 小时(现在是夏令时)。 在我的测试中,我使用了时间 15:00。 让它成为可变的 dst=1 小时(对于我当地的夏令时),我想了解为什么我得到这个输出:

  1. 在俄罗斯 UTC+3,所以 15:00utc + 3 = 18:00
  2. 在俄罗斯 UTC+3,所以 15:00local + 3 = 18:00(dst*0 因为是冬天)
  3. 在俄罗斯 UTC+3,所以 15:00utc + 3 = 18:00
  4. 为什么是17:00???(怎么算的?)
  5. 在基辅 UTC+2,所以 15:00utc + 2 = 17:00
  6. 在基辅 UTC+2,所以 15:00local + 2 = 17:00
  7. 为什么是18:00???(怎么算的?)
  8. 为什么是17:00???(怎么算的?)

Windows 7

时区:(UTC+00:00) 都柏林、爱丁堡、里斯本、伦敦。

文化:英国

DateTime time = TimeZoneInfo.ConvertTime(new DateTime(2018, 11, 23, 15, 0, 0, DateTimeKind.Utc),
     TimeZoneInfo.FindSystemTimeZoneById("Russian Standard Time"));
 Console.WriteLine(time);

 time = TimeZoneInfo.ConvertTime(new DateTime(2018, 11, 23, 15, 0, 0, DateTimeKind.Local),
     TimeZoneInfo.FindSystemTimeZoneById("Russian Standard Time"));
 Console.WriteLine(time);

 time = TimeZoneInfo.ConvertTime(new DateTime(2018, 8, 2, 15, 0, 0, DateTimeKind.Utc),
    TimeZoneInfo.FindSystemTimeZoneById("Russian Standard Time"));
 Console.WriteLine(time);

 time = TimeZoneInfo.ConvertTime(new DateTime(2018, 8, 2, 15, 0, 0, DateTimeKind.Local),
     TimeZoneInfo.FindSystemTimeZoneById("Russian Standard Time"));
 Console.WriteLine(time);

 time = TimeZoneInfo.ConvertTime(new DateTime(2018, 11, 23, 15, 0, 0, DateTimeKind.Utc),
     TimeZoneInfo.FindSystemTimeZoneById("FLE Standard Time"));
 Console.WriteLine(time);

 time = TimeZoneInfo.ConvertTime(new DateTime(2018, 11, 23, 15, 0, 0, DateTimeKind.Local),
     TimeZoneInfo.FindSystemTimeZoneById("FLE Standard Time"));
 Console.WriteLine(time);

 time = TimeZoneInfo.ConvertTime(new DateTime(2018, 8, 2, 15, 0, 0, DateTimeKind.Utc),
    TimeZoneInfo.FindSystemTimeZoneById("FLE Standard Time"));
 Console.WriteLine(time);

 time = TimeZoneInfo.ConvertTime(new DateTime(2018, 8, 2, 15, 0, 0, DateTimeKind.Local),
     TimeZoneInfo.FindSystemTimeZoneById("FLE Standard Time"));
 Console.WriteLine(time);

因为时区 "London" 是 而不是 UTC+0。冬天只有UTC+0,夏天只有UTC+1。

如果您在将日期转换为 "FLE" 之前将其显示为 UTC,您就会明白我的意思。

示例:

var fleTimeZone = TimeZoneInfo.FindSystemTimeZoneById("FLE Standard Time");
var local = new DateTime(2018, 8, 2, 15, 0, 0, DateTimeKind.Local);
var utc = local.ToUniversalTime();
var fle = TimeZoneInfo.ConvertTime(local, fleTimeZone);

Console.WriteLine(TimeZoneInfo.Local);
Console.WriteLine(TimeZoneInfo.Local + ": " + local);
Console.WriteLine(TimeZoneInfo.Utc + ": " + utc);
Console.WriteLine(fleTimeZone + ": " + fle);

(UTC+00:00) Dublin, Edinburgh, Lissabon, London

(UTC+00:00) Dublin, Edinburgh, Lissabon, London: 02.08.2018 15:00:00

UTC: 02.08.2018 14:00:00

(UTC+02:00) Helsinki, Kiew, Riga, Sofia, Tallinn, Wilna: 02.08.2018 17:00:00

正如 nvoigt 所解释的,伦敦的夏令时(称为 BST)是 UTC+1。当您使用 DateTimeKind.Local 时,该值是 本地计算机

因此,要完成您的图表:

4) 伦敦是 UTC+1 (BST),所以 15:00 BST = 14:00 UTC。俄罗斯是UTC+3,所以14:00 + 3 = 17:00

7) 15:00 协调世界时。基辅是 UTC+3 (EEST),所以 15:00 + 3 = 18:00

8) 伦敦是 UTC+1 (BST) 所以 15:00 BST = 14:00 UTC。基辅是 UTC+3,所以 14:00 + 3 = 17:00

所有计算都按预期进行。