Reputation: 907
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
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
Reputation: 18843
Try something like the following Chace
TimeZoneInfo estTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
DateTime estDateTime = TimeZoneInfo.ConvertTimeFromUtc(timeUtc, estTimeZone);
Upvotes: 8
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