Javascript + Dates + jQuery + .Net Web Service, plenty of date related issues

Firstly, let me say that working with dates in javascript is a real pain. I can’t comment on why there is a lack of standardization for dates between browsers, but it sure can make things difficult.

Here are 3 things that I had to overcome that were far from trivial so that I could get my web client sending objects with date properties to my .asmx web service

Problem 1

First problem was that I am sending a date value to a web service using jQuery and Sys.Serialization.JavaScriptSerializer.serialize to serialize the object I am sending. I was getting messages saying that my dates were not valid, even though they were in correct JSON format:

 

1 "Date":"/Date(-62135596800000)/"

 

It turns out this is because the .Net guys have a little trick going on with date serialization where  “Date()” must be surrounded with “\/” instead of just “/” (though it then becomes “\\/” in your javascript to escape the first slash). The stupid thing was that Sys.Serialization.JavaScriptSerializer.serialize was not adding the extra \, which seems a bit of an oversight. When you consider this simple example where an object is retrieved and then sent back to the server:

 

01 $.ajax({
02         type: "POST",
03         url: "/AJAX.asmx/GetObject",
04         data: "{\"id\":123}",
05         contentType: "application/json; charset=utf-8",
06         dataType: "json",
07         success: function (result)
08         {
09             //get the object which contains a date property
10             var myObject = result.d;
11             SaveObject(myObject);
12         },
13     });
14 function SaveObject(o)
15 {
16    //serialize the object
17     var x = Sys.Serialization.JavaScriptSerializer.serialize(o);
18     //SAVE THE OBJECT, BUT THIS FAILS DUE TO INCORRECT DATE SERIALIZATION
19     $.ajax({
20         type: "POST",
21         url: "/AJAX.asmx/SaveObject",
22         data: "{\"object\":" + x + "}",
23         contentType: "application/json; charset=utf-8",
24         dataType: "json",
25         success: function (result)
26         {
27             alert(result.d);
28         }
29    });
30 }

 

 

The simple workaround that I have is just to do a replace in the serialized string to insert the extra “\” characters

 

1 x = x.replace(/\/Date\(/g, "\\/Date(").replace(/\)\//g, ')\\/');

A bit hackish and subject to other parts of the serialization not having )\/ in them, but it seems to work… and now I can send the received object back to the service and it will arrive exactly the same as when it left.

 

 

Problem 2

Trying to figure out why my date’s Year said one thing and did another:

 

1 var date = new Date(2010, 10, 30);
2 alert(date.getDate() + '\/' + date.getMonth() + '\/' + date.getYear());
3 //popup shows "30/10/110"

It seems that different browsers implement getYear() differently; IE will return 2010 but safari will return 110 (the number of years since 1900). To get this working right I needed to use date.getFullYear() which is consistent in returning 2010 in this case.

 

Problem 3

Localization. I was taking my date string “30/10/2010”, splitting it up by the “/” character, and using the date constructor:

 

1 var parts = control.value.split('/');
2 var day = parseInt(parts[0]);
3 var month = parseInt(parts[1]);
4 var year = parseInt(parts[2]);
5 var d = new Date(year, month-1, day);

 

This looked fine on the client, but in the service method on the server the date was showing something like “29/10/2010 12:00pm” instead of “30/10/2010 0:00” – turns out it was a localized time being generated in javascript, so when converted into ticks it was 12 hours out (timezone here is GMT+12). To sort this out UTC needs to be used on the client:

 

1 var parts = control.value.split('/');
2    var day = parseInt(parts[0]);
3    var month = parseInt(parts[1]);
4    var year = parseInt(parts[2]);
5    var d = new Date(Date.UTC(year, month-1, day));
6    //d is now safe to be converted into ticks and serialized to JSON

 

 

 

And there endeth todays javascript date lesson. I hope this saves someone the time that I spent getting it working.

Advertisements
This entry was posted in Javascript, jQuery, Web Devleopment and tagged , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s