views:

58

answers:

5

I've looked and looked and can't seem to come up with the perfect solution. So, since stack overflow is perfect, this will cure my problem.

I'm getting System.String datetimes from a server (Microsoft CRM if you care). They're in SQL format ("2010-07-23T17:14:40-04:00"). I want to read that in as a .net System.DateTime type with the timezone information preserved, then convert it to local time. This process happens in various timezones, and I'm having trouble staying in synch. Basically, I get lots of CRM records from CRM server (which seems to stamp all the timezones with this Brazilian time (-4)), and I want to write down in my config file the latest one I saw (so I don't go back and pick up values that I already have). I would like to write it down in local time, though. Here's a distillation

I want to take the string "2010-07-23T17:14:40-04:00" and, run some code:

System.Datetime Get_Local_DT(string val);

that will return "2010-07-23 15:14:40" in Central time (-6) and "2010-07-23 16:14:40" in Eastern Time (-5). Let me know what you think.

A: 

???

 private DateTime Get_Local_DT(string strTimestamp, int iUTCOffset)
    {
        DateTime _dt = DateTime.MinValue;
        try
        {
            DateTime dt = DateTime.Parse(strTimestamp);
            DateTime _returnDateTime = dt.ToUniversalTime().AddHours(iUTCOffset);
            return _returnDateTime;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
        return _dt;
    }
Randster
A: 

I think you should use the System.DateTimeOffset type which solves your issue.

String d = "2010-07-23T17:14:40-04:00";
DateTimeOffset dt = DateTimeOffset.Parse(d);
Console.WriteLine(dt.LocalDateTime + " " + dt.ToOffset(TimeSpan.FromHours(-2)));
Benni
A: 

You could parse the string into a DateTime object using

string sqlDate = "2010-07-23T17:14:40-04:00";

DateTime dt = DateTime.Parse(sqlDate);

Next, you could use the following statement to format it:

dt.ToString("yyyy-MM-dd HH:mm:ss", System.Globalization.DateTimeFormatInfo.InvariantInfo);

I tried this code:

void Main()
{
    string sqlDate = "2010-07-23T17:14:40-04:00";

    DateTime dt = DateTime.Parse(sqlDate);

    Console.WriteLine(dt.ToString("yyyy-MM-dd HH:mm:ss", System.Globalization.DateTimeFormatInfo.InvariantInfo));
}

Output: 2010-07-24 02:44:40

I am in IST. I hope this helps.

Pankaj Sharma
The code posted by Randster works well. However, it may need to format the date accordingly i.e. yyyy-MM-dd HH:mm:ss
Pankaj Sharma
+1  A: 

Save them as universal time:

   DateTime t = DateTime.Parse(str);
   t.ToUniversalTime(); // save this

Then show saved time as local:

   DateTime t = DateTime.Parse(str);
   t.ToLocalTime(); // show this

Always work with universal time, think about local as just a view in mvc.

Grozz
+1  A: 

The reason your times are stamped with the Brazilian time is that is the timezone attached to the user performing the query. CRM stores universal in the database and the filtered views generate that string based on the current user. This way whenever you open up a record in CRM you get a date with a time for your timezone.

If all your doing is saving the date/time so you can check against it later, I agree with storing as UTC and doing UTC comparisons.

Note that if you're using any ToLocalTime methods, you are showing Local Time on the server and NOT the actual users local time (unless they're in the same timezone as the server). I guess how important this is to you depends on how many timezones you support (1 or many) and where your server is located.

benjynito