JavaScriptSerializer is subtracting one day from date
Asked Answered
F

3

20

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.

Flotation answered 21/2, 2013 at 13:21 Comment(1)
Solution 1: muck around with timezones, etc. Solution 2: just store the year, month and day as separate values, then recombine after deserialization.Flatwise
B
20

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!
Blabbermouth answered 21/2, 2013 at 13:30 Comment(7)
This is the documented behavior, albeit very unclear.Flatwise
DateTime startDate = new DateTime(2012, 1, 20).ToUniversalTime(); it sets the startDate to 19 jan? and on deserialize getting the same... Why it is happening?Flotation
blog.devarchive.net/2008/02/… Here is a blog explaining the problem quite in detailTrinette
@ZaheerAhmed - it's changing the timezone. There's an implicit midnight attached to your date, so your are probably losing a few hours in the timezone shift, causing the date to change.Flatwise
My timezone is PST, how can I input and get output in the same timezone.Flotation
This - and many other reasons - are why you should use Json.Net instead of the JavaScriptSerializerInsomnolence
@ZaheerAhmed - Consider using a DateTimeOffset and serialize in ISO8601 format instead, using Json.Net instead of the JavaScriptSerializer.Insomnolence
T
5

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

Tachistoscope answered 7/1, 2016 at 11:56 Comment(0)
F
2

On deserializing JavaScriptSerializer giving me output in UTC (Universal Time) which due to change in hours change the date. As Brad Christie suggested to change DateTime to UTC it can solve the problems.

But actually there is no need to change the:

DateTime startDate = new DateTime(2012, 1, 20).ToUniversalTime();

as it is already taking it as Universal Time. So I just convert the output of deserialize to LocalTime:

 DateTime afterDeserialize= serializer.Deserialize<DateTime>(serializeDate);
 afterDeserialize.ToLocalTime();

it solved the issue.

Flotation answered 21/2, 2013 at 13:48 Comment(2)
Funny, was just in the middle of typing that up in an update to my answer. ;-)Blabbermouth
:), marked your answer correct, and just put this here, so it helps othersFlotation

© 2022 - 2024 — McMap. All rights reserved.