Search code examples
c#datetimeutcdst

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


There are some timezones which switch to Daylight saving time and not. I know that Russia doesn't switch to this time and Ukraine switches to Daylight saving time.

As I know from this link .NET TimeZoneInfo from Olson time zone Moscow uses Russian Standard Time and Kiev(Ukraine) uses FLE Standard time.

My test is:

  1. Winter, Russia, DateTimeKind.Utc

  2. Winter, Russia, DateTimeKind.Local

  3. Summer, Russia, DateTimeKind.Utc

  4. Summer, Russia, DateTimeKind.Local

  5. Winter, Kiev, DateTimeKind.Utc

  6. Winter, Kiev, DateTimeKind.Local

  7. Summer, Kiev, DateTimeKind.Utc

  8. Summer, Kiev, DateTimeKind.Local

My PC time is (UTC+00:00) London +1 hour (now is Daylight saving time). In my tests I used time 15:00. Let it be variable dst=1 hour (for my local Daylight saving time), I want to understand why I get this output:

  1. In Russia UTC+3, so 15:00utc + 3 = 18:00
  2. In Russia UTC+3, so 15:00local + 3 = 18:00 (dst*0 since it is winter)
  3. In Russia UTC+3, so 15:00utc + 3 = 18:00
  4. Why it is 17:00 ??? (how it is calculated?)
  5. In Kiev UTC+2, so 15:00utc + 2 = 17:00
  6. In Kiev UTC+2, so 15:00local + 2 = 17:00
  7. Why it is 18:00 ??? (how it is calculated?)
  8. Why it is 17:00 ??? (how it is calculated?)

Windows 7

Time zone: (UTC+00:00) Dublin, Edinburgh, Lisbon, London.

Culture: United Kingdom

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);

enter image description here


Solution

  • As nvoigt explained, London's summer time (called BST) is UTC+1. When you use DateTimeKind.Local, the value is local to your machine.

    Thus, to finish out your chart:

    4) London is UTC+1 (BST) so 15:00 BST = 14:00 UTC. Russia is UTC+3, so 14:00 + 3 = 17:00

    7) 15:00 UTC. Kiev is UTC+3 (EEST), so 15:00 + 3 = 18:00

    8) London is UTC+1 (BST) so 15:00 BST = 14:00 UTC. Kiev is UTC+3, so 14:00 + 3 = 17:00

    All calculations are working as expected.