I\'m facing an issue while converting dates between my server and client where both is running in Germany. The Regional settings on the client machines could be set to both
I realize the question is for C#, but if all you want to do is a single conversion you can do this from the PowerShell command line:
$d = [DateTime]::Parse("04/02/2014 17:00:00")
$gmt = [TimeZoneInfo]::FindSystemTimeZoneById("GMT Standard Time");
[TimeZoneInfo]::ConvertTime($d, $gmt, [TimeZoneInfo]::Local)
This script would convert 17:00 UK time into your local time zone. For me, that would be CST. It's interesting to note that if I had set the date to 03/27/2014, the result would be different because the UK daylight saving time kicks in on different dates that the US.
The better approach to deal with local times is store them in unified representation such as UTC.
So you can convert all input times to UTC (via .ToUniversalTime()
), and store (or transmit) its value. When you need to show it just convert back by using .ToLocalTime()
.
So you avoid rquirements to know which time zone was original value and can easily show stored value in different timezones.
Also you can avoid incoming troubles where you have to write specific logic for processing time in next timezone trying to figure out how to convert them amongs all available.
This is what I do:
var BritishZone = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
DateTime dt = DateTime.SpecifyKind(DateTime.UtcNow, DateTimeKind.Unspecified);
DateTimeInBritishLocal = TimeZoneInfo.ConvertTime(dt, TimeZoneInfo.Local, BritishZone);
I needed to add the SpecifyKind part or the ConvertTime throws an exception
Use TimeZoneInfo.ConvertTime to convert original input timezone (CET) to target timezone (UK).
public static DateTime ConvertTime(
DateTime dateTime,
TimeZoneInfo sourceTimeZone,
TimeZoneInfo destinationTimeZone
)
Full guidance on MSDN here:
Converting Times Between Time Zones
Modified code sample from MSDN:
DateTime ceTime = new DateTime(2007, 02, 01, 08, 00, 00);
try
{
TimeZoneInfo ceZone = TimeZoneInfo.FindSystemTimeZoneById("Central Europe Standard Time");
TimeZoneInfo gmtZone = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
Console.WriteLine("{0} {1} is {2} GMT time.",
ceTime,
ceZone.IsDaylightSavingTime(ceTime) ? ceZone.DaylightName : ceZone.StandardName,
TimeZoneInfo.ConvertTime(ceTime, ceZone, gmtZone));
}
catch (TimeZoneNotFoundException)
{
Console.WriteLine("The registry does not define the required timezones.");
}
catch (InvalidTimeZoneException)
{
Console.WriteLine("Registry data on the required timezones has been corrupted.");
}
I think you're converting to UTC (instead of UK) time. Since there is still summer time in Central Europe (event if the temperatures say otherwise), the difference is +2 hours until October, 31st.
If you know that you're converting from Germany to UK (i.e. CEST to BST in summer and CET to GMT in winter), why you don't just subtract 1 hour?
If you want the time zone information for UK, you can construct it using
var britishZone = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
Then you could convert the date using
var newDate = TimeZoneInfo.ConvertTime(serverDate, TimeZoneInfo.Local, britishZone);