Chace Fields
Chace Fields

Reputation: 907

How to convert a datetime to specific timezone in c#?

I need help converting a DateTime to a specific time zone. What I have below is not working correctly.

gmTime = 03/02/2013 1:00:00 AM

 TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
 var time = timeZoneInfo.ConvertTime(gmTime, timeZone);

When I debug the value of time, which should be 03/01/2013 8:00:00 PM when the zone is applied, it comes back as 03/02/2013 1:00:00 AM.

If I do time.ToLocalTime() then I get the correct value. However, I need to convert time to different time zones.

Upvotes: 22

Views: 25666

Answers (3)

David
David

Reputation: 4953

The following code will let you go from any arbitrary time zone to any other. We make use of DateTimeOffset which will allow you to pass the UTC Offset in. You may consider whether just using DateTimeOffset instead of DateTime will suit your needs. But if you want to use DateTime instead, here is some code that will do the conversion for you:

public DateTime ChangeTimeZone(DateTime dateTimeInput, TimeZoneInfo sourceTimeZone, TimeZoneInfo destTimeZone)
{
    var zonedTime = new DateTimeOffset(DateTime.SpecifyKind(dateTimeInput, DateTimeKind.Unspecified),
                                       sourceTimeZone.GetUtcOffset(dateTimeInput));
    var utcTime = zonedTime.UtcDateTime;
    
    return TimeZoneInfo.ConvertTime(utcTime, destTimeZone);
}

You may notice that we explicitly call SpecifyKind and set it to Unspecified. The reason for this is because if the Kind is specified on the dateTimeInput then the UtcOffset must match that Kind -- so if it is DateTimeKind.Utc, then that number must be 0. If it is Local, then it must be whatever the local time offset is or you will get an exception. Of course, if you already know the Kind then you could skip this function and just go straight to TimeZoneInfo.ConvertTime.

Upvotes: 2

MethodMan
MethodMan

Reputation: 18843

Try something like the following Chace

TimeZoneInfo estTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
DateTime estDateTime = TimeZoneInfo.ConvertTimeFromUtc(timeUtc, estTimeZone);

Upvotes: 8

MerickOWA
MerickOWA

Reputation: 7592

DateTime objects have a "Kind" variable which helps TimeZoneInfo know how to treat it. In the MSDN documentation for TimeZone.ConvertTime it has the following:

DateTimeKind.Local, Converts the local time to the time in destinationTimeZone.

DateTimeKind.Utc, Converts Coordinated Universal Time (UTC) to the time in destinationTimeZone.

DateTimeKind.Unspecified, Assumed to be Local.

For example:

  Console.WriteLine("Local time zone is '{0}'.", TimeZoneInfo.Local.Id);

  var gmTime          = new DateTime(2013, 03, 02, 01, 00, 00, DateTimeKind.Utc);
  var localTime       = new DateTime(2013, 03, 02, 01, 00, 00, DateTimeKind.Local);
  var unspecifiedTime = new DateTime(2013, 03, 02, 01, 00, 00);

  var timeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");

  var gmTimeConverted           = TimeZoneInfo.ConvertTime(gmTime,          timeZone); // 03/02/2013 8:00:00AM
  var localTimeConverted        = TimeZoneInfo.ConvertTime(localTime,       timeZone); // 03/02/2013 
  var unspecifiedTimeConverted  = TimeZoneInfo.ConvertTime(unspecifiedTime, timeZone);

  Console.WriteLine("Converting GMT         to EST: {0}", gmTimeConverted);
  Console.WriteLine("Converting Local       to EST: {0}", localTimeConverted);
  Console.WriteLine("Converting Unspecified to EST: {0}", unspecifiedTimeConverted);

Results in:

Local time zone is 'Pacific Standard Time'.
Converting GMT         to EST: 3/1/2013 8:00:00 PM
Converting Local       to EST: 3/2/2013 4:00:00 AM
Converting Unspecified to EST: 3/2/2013 4:00:00 AM

Or if your local timezone is 'Eastern Standard Time' you get these results

Local time zone is 'Eastern Standard Time'.
Converting GMT         to EST: 3/1/2013 8:00:00 PM
Converting Local       to EST: 3/2/2013 1:00:00 AM
Converting Unspecified to EST: 3/2/2013 1:00:00 AM



If you'd like TimeZoneInfo to treat 'Unspecified' like Utc, you should function like TimeZoneInfo.ConvertTimeFromUtc. Again from MSDN documentation

DateTimeKind.Local, Throws an ArgumentException.

DateTimeKind.Unspecified or DateTimeKind.Utc, Converts from Coordinated Universal Time (UTC).

Upvotes: 21

Related Questions