We have a server which is failing to handle daylight saving time correctly wrt C# DateTime instances converting from UTC to local time. We are in the UK so have our servers set to "(UTC+00:00) Dublin, Edinburgh, Lisbon, London" region.
Symptom:
DateTime utcTime = new DateTime(2020, 10, 15, 23, 53, 20, DateTimeKind.Utc);
DateTime localTime = utcTime.ToLocalTime();
Console.WriteLine($"UTC time: {utcTime:s}");
Console.WriteLine($"Local time: {localTime:s}");
UTC time: 2020-10-15T23:53:20
Local time: 2020-10-15T23:53:20 // should be 2020-10-16T00:53:20
Investigation:
var gmt = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
Console.WriteLine("GMT:");
Console.WriteLine($"ID: {gmt.Id}");
Console.WriteLine($"DisplayName: {gmt.DisplayName}");
Console.WriteLine($"DST: {gmt.SupportsDaylightSavingTime}");
var local = TimeZoneInfo.Local;
Console.WriteLine("Local:");
Console.WriteLine($"ID: {local.Id}");
Console.WriteLine($"DisplayName: {local.DisplayName}");
Console.WriteLine($"DST: {local.SupportsDaylightSavingTime}");
On "normal" workstations and servers, the output is:
GMT:
ID: GMT Standard Time
DisplayName: (UTC+00:00) Dublin, Edinburgh, Lisbon, London
DST: True
Local:
ID: GMT Standard Time
DisplayName: (UTC+00:00) Dublin, Edinburgh, Lisbon, London
DST: True
On the rogue server, it is:
GMT:
ID: GMT Standard Time
DisplayName: (UTC+00:00) Dublin, Edinburgh, Lisbon, London
DST: True
Local:
ID: GMT Standard Time
DisplayName: GMT Standard Time
DST: False
What could be the origin of this "GMT Standard Time" time zone info instance that has the same ID but a different name and DST support?
"rogue" server is Windows Server 2012 R2. I don't see anything obviously out of place in the registry keys
e.g. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\ has a "GMT Standard Time" key under it which declares the name "(UTC+00:00) Dublin, Edinburgh, Lisbon, London"
Under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\ the TimeZoneKeyName value is "GMT Standard Time"
EDIT: We're running .NET framework code. The UTC-to-local conversion failure shows up in both .NET v2 and .NET v4.7.2.