Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScriptSerializer is subtracting one day from date

Tags:

I am using JavaScriptSerializer for serializing DateTime, but when I deserialize it show one day less from the date it get serialize:

Here is test:

  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);

firstly I thougt it because of javascript datetime format but as I know for javascript Month is zero index 0=January, but I am getting one day less than the original date.

like image 869
Zaheer Ahmed Avatar asked Feb 21 '13 13:02

Zaheer Ahmed


2 Answers

It's not losing a day arbitrarily, it's converting to a UTC date (or I should say using the date in a UTC date format) so when it's unserialized it you're no longer within your personal time zone. It's basically performing:

DateTime whateverDate = /* incoming date */;
long ticks = whateverDate.ToUniversalTime() // make UTC
  .Subtract(new DateTime(1970, 1, 1))       // subtract UNIX Epoch
  .TotalMilliseconds();                     // get milliseconds since then
// push in to the "\/Date(ticks)\/" format
String value = String.Format(@"\/Date({0})\/", ticks);

However, try the following:

// or you rely on it serializing, then bring it back to your own local time
// (apply the time zone).
afterDeserialize = afterDeserialize.ToLocalTime();

You'll now have the UTC time back to your local time (with time zone applied).


To Pass your test:

DateTime startDate              = new DateTime(2012,1,20);
JavaScriptSerializer serializer = new JavaScriptSerializer();
String serializeDate            = serializer.Serialize(startDate);
DateTime afterDeserialize       = serializer.Deserialize<DateTime>(serializeDate)
                                  .ToLocalTime(); // Note: this is added

Assert.Equals(startDate, afterDeserialize); // pass!
like image 177
Brad Christie Avatar answered Sep 30 '22 06:09

Brad Christie


I had the same problem and solved it by using

Newtonsoft.Json.JsonConvert.SerializeObject()

instead of

new System.Web.Script.Serialization.JavaScriptSerializer().Serialize().

The latter call stores your DateTime converted to some random timezone (GMT+0 seems to be hardcoded).

like image 32
mischka Avatar answered Sep 30 '22 05:09

mischka