2

The thing I want to do is quite simple:

    private static TimeZoneInfo Tzi = // ... custom timeZone I've set;
    public static DateTime ToTimeZone(DateTime dateTime, TimeZoneInfo target)
    {
        return TimeZoneInfo.ConvertTime(dateTime, Tzi, target);
    }

Idea is - all dates that come to the server are automatically converted to certain TimeZone and saved like that to DB (UTC, Central US, Pacific US, whatever).

And this works quite well as long as timezone set on the server is same as Tzi. However, when that's not true, conversion fails - when creating DateTime instance .NET sets it to TimeZone of the machine and then TimeZoneInfo.ConvertTime(dateTime, Tzi, target) processes my request in a funky way. For example, let's say that Server TimeZone is Pacific (UTC -8), I set Tzi to Central (UTC -6), and I target Singapure (UTC +8).

Now when I call TimeZoneInfo.ConvertTime(dateTime, Tzi, target) first "converts" dateTime from UTC -8 to UTC -6 (Tzi time zone), adding 2 hours... and only then from Tzi to target.

Is there a way to signal to TimeZoneInfo.ConvertTime that dateTime I am sending is in TimeZone I am passing in as from parameter, and not in the TimeZone of server?

EDIT: OK, both answers are great recommendations, but it seems I have different kind of trouble. TimeZoneInfo.ConvertTime(dateTime, Tzi, target) seems to be working correctly, and the real culprit is actually:

return Json(new {data}, JsonRequestBehavior.AllowGet);

that outputs dates like: "Created":"/Date(1346810072950)/". I've confirmed that sent date is different depending on TimeZone on the server (AppPool restart is needed after changing server's TimeZone). Anyone have experience with this and suggestion on how to influence the way ASP.NET MVC outputs dates in JSON that's sent back to client?

nikib3ro
  • 20,366
  • 24
  • 120
  • 181
  • 2
    Related: http://stackoverflow.com/questions/2532729/daylight-saving-time-and-timezone-best-practices – Oded Sep 04 '12 at 09:09

2 Answers2

3

ConvertTime should do the job. Maybe your issue is the DateTime.Kind.

See the following example:

// Gets current local date
// Returns 04/09/12 11:30 in my case
var date = DateTime.Now;

// Sets DateTime as Unspecified kind (not local nor UTC)
// Returns same date as before, but the date is not tagged as "local"
date = DateTime.SpecifyKind(date, DateTimeKind.Unspecified);

// Converts the current date, specified as UTC+12, into a date specified as UTC-11
// Returns 03/09/12 12:30 in my case, which is the expected result
// (23 hours between previous date and result)
var zz = TimeZoneInfo.ConvertTime(
    date,
    TimeZoneInfo.FindSystemTimeZoneById("UTC+12"),
    TimeZoneInfo.FindSystemTimeZoneById("UTC-11"));
ken2k
  • 48,145
  • 10
  • 116
  • 176
2

You can use DateTimeOffset instead of DateTime - this structure includes a timezone offset property, so when creating instances of it you should specify what offset to use.

Oded
  • 489,969
  • 99
  • 883
  • 1,009