16

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 UK or Germany.I recieve a date from the server which is CET format, and I need to represent this time on UI as UK time. For example a time recieved from server like say, 01/07/2010 01:00:00 should be represented on the UI as 01/07/2010 00:00:00. I have written a converter for this purpose, however while running it 'am getting a time difference of 2 hours.Below is the code, please can you help?

public class LocalToGmtConverter : IDateConverter
{
    private readonly TimeZoneInfo timeZoneInfo;

    public LocalToGmtConverter()
        : this(TimeZoneInfo.Local)
    {

    }
    public LocalToGmtConverter(TimeZoneInfo timeZoneInfo)
    {
        this.timeZoneInfo = timeZoneInfo;
    }

    public DateTime Convert(DateTime localDate)
    {
        var utcKind = DateTime.SpecifyKind(localDate, DateTimeKind.Utc);
        return utcKind;
    }

    public DateTime ConvertBack(object fromServer)
    {
        DateTime serverDate = (DateTime)fromServer;

        var utcOffset = timeZoneInfo.GetUtcOffset(serverDate);

        var uiTime = serverDate- utcOffset;

        return uiTime;

    }
}
Mike
  • 3,204
  • 8
  • 47
  • 74
  • 2
    Are you getting German time or GMT from the server? – Oded Oct 27 '10 at 15:32
  • 2
    Related question: http://stackoverflow.com/questions/2532729/daylight-saving-time-and-timezone-best-practices – Oded Oct 27 '10 at 15:32
  • 2
    The better approach have both times in UTC and convert to local as needed – Nick Martyshchenko Oct 27 '10 at 15:35
  • GMT is defunct now and has been replaced by UTC. They tell me that there is a difference, but as far as I can tell, the only difference is that it's not named after a locatlity. Maybe the difference is that it never shifts with DST and GMT did; I don't know. – Brad Oct 27 '10 at 15:42
  • Wait until after this weekend. The conversion will work properly then until next March because UK time will coincide with UTC. – JeremyP Oct 27 '10 at 15:47
  • @Nick Martyshchenko: I think you should make that an answer because I think it is the correct approach. – JeremyP Oct 27 '10 at 15:49
  • @JeremyP, thank you. I converted my comment to answer. – Nick Martyshchenko Oct 27 '10 at 16:09

5 Answers5

31

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);
MartinStettner
  • 28,719
  • 15
  • 79
  • 106
  • 1
    Yep, true UTC and the British timezone (often called something like UTC Dublin, Edinburgh, Lisbon, London in the UI) are not the same thing. YOu need to get the British timezone info and that should cover the daylight saving time for you. – Steve Oct 27 '10 at 15:43
  • 1
    FYI GMT does not correct for day light savings time so for instance right now it is 1 hour behind. – Jack Aug 27 '21 at 08:52
4

This is what I do:

    var BritishZone = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");

    DateTime dt = DateTime.SpecifyKind(DateTime.UtcNow, DateTimeKind.Unspecified);

    DateTime DateTimeInBritishLocal = TimeZoneInfo.ConvertTime(dt, TimeZoneInfo.Utc, BritishZone);

I needed to add the SpecifyKind part or the ConvertTime throws an exception

noelicus
  • 14,468
  • 3
  • 92
  • 111
2

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.");
}
Steve Townsend
  • 53,498
  • 9
  • 91
  • 140
1

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.

Nick Martyshchenko
  • 4,231
  • 2
  • 20
  • 24
  • I think the issue here is that he does not want it in local time, he is in Germany (CET) and wants to display the time in the UK (GMT). – Steve Oct 27 '10 at 16:07
  • @Steve Haigh, thanks to point, but he can convert value from UTC to whatever timezone he wants without any problem. But OP says about receiving and showing dates from server, so I think his app just works in different timezones. – Nick Martyshchenko Oct 27 '10 at 16:13
-3

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.

Simon Gillbee
  • 3,932
  • 4
  • 35
  • 48