Wednesday, November 13, 2013

C# : JavaScriptSerializer and Time Zone Issue

Learning AngularJS; Guide for beginners:

Recently I was working on a module which include DateTime object. I found some interesting facts about this, which I want to share with my blog readers.I serialized DateTime object with c# JavaScriptSerializer, but when I deserialize the object it give me one day less from the date it get serialize



Example I serialized the date of 20th Jan 2012 date and assign it to a string, but when I deserialize the same string it give me the 19th Jan 2012



Here is code:

DateTime startDate=new DateTime(2012,1,20);//set the 20th of January
JavaScriptSerializer  serializer=new JavaScriptSerializer();
string serializeDate= serializer.Serialize(startDate);
DateTime afterDeserialize= serializer.Deserialize<datetime>(serializeDate);//I get 19th of Jan
Assert.Equals(startDate, afterDeserialize);

I tried to find out the reason posted it on StackOverflow and interestingly I found that actually It was not subtracting one day, but it converted the time-zone to UTC. So when it deserialized the DateTime object which was in PST(Pakistan Standard Time) time-zone, it was not in PST but in UTC. It's basically converted my PST DateTime object to UTC and then converted to tick like:

DateTime dateTimeObjectOfAnyTimeZone = /* incoming date */;
long ticks = dateTimeObjectOfAnyTimeZone.ToUniversalTime() // make UTC
  .Subtract(new DateTime(1970, 1, 1))     // subtract UNIX Epoch
  .TotalMilliseconds();     // get milliseconds since 1st jan 1970

// convert it into "\/Date(ticks)\/" format
string tickValue = String.Format(@"\/Date({0})\/", ticks);
return tickValue;

so on deserializing this string it gives me DateTime in UTC which was of 9 hours difference from my current time zone so subtracting 9 hours from 20th Jan 2012 12:00 AM converted it into 19th Jan 2012
So to get the correct output I tried:

// apply current TimeZone after deserializing tick using ToLocalTime()
// (apply the time zone).
DateTime afterDeserialize= serializer.Deserialize<datetime>(serializeDate);
afterDeserialize = afterDeserialize.ToLocalTime();


Now have the UTC time back to PST local time (with time zone applied)and it was my required 20th Jan 2012.

1 comment:

  1. If you need a timezone in your data use DateTimeOffset. Other than that you should assume UTC. Don't use JavaScriptSerializer, instead use Json.Net; install-package Newtonsoft.Json

    ReplyDelete

Life insurance policy, bank loans, software, microsoft, facebook,mortgage,policy,