dragonfly
dragonfly

Reputation: 17773

Convert DateTime.Now from one UTC time zone to another

Sample scenario:

I have a server in time zone +13.00 (for instance), and my users work in time zone +2.00.

How can I cause:

DateTime.Now

called on ther server to return a time that is in UTC +2.00 ? (or convert DateTime.Now result to +2.00 time zone)

Upvotes: 0

Views: 239

Answers (2)

Jeppe Stig Nielsen
Jeppe Stig Nielsen

Reputation: 61912

The ordinary DateTime does not in itself contain information about time zone. (It does contain a Kind hinting if it's known to be a local time or universal time.)

Consider the possibility of using UTC time in the communication between server and user. Before you send, use .ToUniversalTime(), and after you receive, use .ToLocalTime(). Note that if you perform arithmetic on DateTime values, the Kind may not be conserved, and then there's the risk of accidentally performing .ToLocalTime() etc. more than once.

There's also the possibility to use DateTimeOffset instead. It contains the time zone together with the date and time.

var nowWithZone = DateTimeOffset.Now;

You can convert to other DateTimeOffset with methods such as nowWithZone.ToLocalTime() and nowWithZone.ToOffset(TimeSpan.FromHours(+2.0)).

You can convert to ordinary DateTime with properties like nowWithZone.LocalDateTime, nowWithZone.UtcDateTime, and nowWithZone.DateTime.

Finally, if this is too confusing or too simple for your needs, there's the possibility to use Noda time.

Upvotes: 1

James
James

Reputation: 82096

You would use the TimeZoneInfo.ConvertTime method. This allows you to pass in the DateTime you want to convert and the source/destination time zones.

Example usage:

var localTime = DateTime.Now;
try
{
   Console.WriteLine("Local time: {0}", localTime);
   TimeZoneInfo destTz = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
   var pacificTime = TimeZoneInfo.ConvertTime(localTime, TimeZoneInfo.Local, destTz);
   Console.WriteLine("Pacific time: {0}", pacificTime);
}
catch (TimeZoneNotFoundException)
{
    Console.WriteLine("The registry does not define the Pacific Standard Time zone.");
}                           
catch (InvalidTimeZoneException)
{
    Console.WriteLine("Registry data on the Pacific Standard Time zone has been corrupted.");
}

If you are always converting the local time zone (i.e. your not explicitly saying convert from X timezone to Y), then you can use the other TimeZoneInfo.ConvertTime overload which doesn't take the sourceTimeZone parameter. The time zone is worked out from the DateTime.Kind property of the source date (in your case, DateTime.Now would imply local anyway).

Upvotes: 2

Related Questions