How I handle JSON dates returned by ASP.NET AJAX
AJAX, ASP.NET, JavaScript, jQuery By Dave Ward on April 27th, 2009
The problem of how to handle dates in JSON is one of the more troublesome issues that may arise when directly calling ASP.NET AJAX web services and page methods.
Unlike every other data type in the language, JavaScript offers no declarative method for expressing a Date. Consequently, embedding them within JSON requires a bit of fancy footwork. Since the question of how I handle this problem is something asked often in emails and in comments on other posts here, I want to address the topic with its own post.
To that end, I will attempt to explain what exactly the problem is with dates in JSON, how ASP.NET AJAX solves it, and my alternative solution that I believe is easier and works just as well in most cases.
What’s the problem?
The fundamental problem is that JavaScript does not provide a way to declaratively express Date objects. You may previously have seen this described as (the lack of) a Date literal.
What are literals? To illustrate, these are literals for several other data types:
// String 'foo'; // Number 3.14; // Boolean true; // Array [1, 2, 3, 5, 7]; // Object { pi: 3.14, phi: 1.62 };
Unfortunately, when it comes to dates, the lack of a literal means that the only way to create one is by explicitly initializing a Date object:
// Correct. new Date('4/26/09'); // Correct (the month is 0 indexed, hence the 3). new Date(2009, 3, 26); // Incorrect. This is a string, not a Date. '4/26/09';
While this limitation is fine when writing client-side JavaScript code, it leaves us without a good way to transmit dates within JSON objects.
How ASP.NET AJAX handles it
While the lack of a date literal is a problem, it’s certainly not without solution.
In fact, ASP.NET AJAX already handles this if you’re using MicrosoftAjax.js to call your services. You may not have even noticed as server-side DateTime values are transparently converted into JavaScript Date objects on the client-side.
For example, consider this web service:
[System.Web.Script.Services.ScriptService] public class DateService : System.Web.Services.WebService { [WebMethod] public DateTime GetDate() { return new DateTime(2009, 4, 26); } }
If you consume that web service with jQuery (or any method that circumvents the ScriptManager), you’ll find that ASP.NET AJAX serializes the DateTime as an escaped JavaScript Date initializer:
{"d":"\/Date(1240718400000)\/"}
Note: If you’re unsure about why the “d” is there, be sure to see my recent post about this security feature which was added in ASP.NET 3.5.
On the client-side, MicrosoftAjax.js uses a regular expression to isolate any Date constructors and then eval() to initialize Date objects. The end result is that proper JavaScript Date objects are instantiated for every DateTime value returned.
However, if you’re not using MicrosoftAjax.js (i.e. the ScriptManager) to call your services, you’ve got a bit of a mess to decode. You can use regex machinations to work around the problem, but is that really necessary?
How I handle it
Consider why you want to send a DateTime to the client-side to begin with. Most often, you’re displaying a string representation of it and have no need for the proper JavaScript Date object.
What’s more, if you end up with a JavaScript Date object, you’ll probably use additional code or a JavaScript library to display it in a user-friendly format.
As much as I appreciate a clever workaround, I’d much rather avoid the problem completely. Rather than jump through all of these hoops to instantiate a JavaScript Date object on the client-side and then format it, I suggest simply returning a formatted string.
For example, we might modify the previous example like so:
[System.Web.Script.Services.ScriptService] public class DateService : System.Web.Services.WebService { [WebMethod] public string GetDate() { return new DateTime(2009, 4, 26).ToLongDateString(); } }
Now, calling the service will return this JSON:
{"d":"Sunday, April 26, 2009"}
No more regular expressions. No more JavaScript Date objects. No more worrying about formatting the data on the client-side.
Even better, no functionality is lost. If we need to instantiate Dates, we still can.
Still want Dates?
Even if you do end up needing JavaScript Date objects, DateTime strings are sufficient for instantiating them. JavaScript’s Date constructor is very flexible:
// ASP.NET AJAX form var foo = new Date(1240718400000); // DateTime.ToLongDateString() form var bar = new Date('Sunday, April 26, 2009'); // DateTime.ToShortDateString() form var baz = new Date('4/26/2009'); // true! foo === bar === baz;
By delaying string-to-Date conversions until truly necessary, we save effort on the server- and client-side. Not only that, but we have the option of retaining both the formatted string and the JavaScript Date to use as desired.
The best of both worlds.
Possibly related posts
What do you think? Your comments are welcome.
I appreciate all of your comments, questions, and other feedback, but please try to stay on topic. If you have a question unrelated to this post, I recommend posting on the ASP.NET forums or Stack Overflow instead.
If you're replying to an existing comment, please use the threading feature. To do this, click the "Reply to this comment" link underneath the comment you're replying to.

Your comments
Dave, great point about returning a formatted date and whenever possible I actually do that.
But I think the real issue though isn’t a single date, but a date on an object or a list of objects. There’s no easy way to format those dates by ‘hand’ because you have nowhere to store them (you can’t store a string on the date property itself in the .NET code because of strong typing).
When possible, I select out an anonymous type and return a type of IEnumerable. That way, I can format the date while I’m returning it.
As seen in this code, for example: http://encosia.com/2008/08/20/easily-build-powerful-client-side-ajax-paging-using-jquery/
One thing to note is the extreme cultural sensitivity of DateTime.ToLongDateString().
If, in your web methods, you set the current thread’s current culture to reflect the browser’s preferred language (I do this manually as I don’t know how to get ASP.NET to do it), then the long date string can be highly variable in terms of both layout/format and the actual words used for day and month.
E.g. if I call DateTime.Now.ToLongDateString(); with the current thread’s culture set to “fr-FR”, I get (on this day): “mardi 28 avril 2009″.
Ergo, formatting using ToLongDateString (and similar) is ideal for preparing culturally correct date strings for end-user display, but less than ideal if you ever want to convert that string to a Date object. And as with dates, so with floating-point numbers.
Often I have my web methods return both JSON-serialized date and floating-point number objects, _and_ the culturally correct textual representations of those dates and numbers, for display. This separation works really well and allows me to easily solve a number of problems in the client-side JS.
For conversion of ASP.NET provided dates, I do use the ScriptManager, so I can let Microsoft do the work. If MS AJAX hasn’t converted to Date for you, you can call their static method Sys.Serialization.JavaScriptSerializer.deserialize().
If I wasn’t using the ScriptManager, however, I’d probably use the millisecond count form (‘1240718400000′) to rule out the possbility of cultural variation.
I was just about to tackle this issue on my website. Weird coincidence that I decided to check my rss reader before working on it.
Thanks
I like the article but… You only address one scenario. That is of when you pass back a Date from a WebMethod. A much more realistic scenario is when you pass back an object say an OrderRecord with public properties SubmittedDate and ApprovedDate the above solution would not fix this problem. I am not the creator of the plug-in but if you are using jQuery with objects you should use the jmsajax plugin(jQuery Microsoft Ajax) which handles the date issues as well as having to access everything with “d.value” as opposed to “value”.
This still works well in those types of scenarios.
Generally, I’d be using a DTO there (real objects are usually too complex to expose directly to the client), so translating the dates to strings during that step is no problem.
Otherwise, I’m probably selecting out an anonymous type and converting the DateTimes to strings at the same time (see the example in reply to Rick above).
Yup, exactly what I do. I almost never return the original object(s), but project into data transfer object(s) where I have precise control over which data items are returned to the client, and what types they have.
When you are dealing with a collection, LINQ projections coupled with anonymous types are so useful for this.
(Have been easing myself into LINQ over the last couple of months, just on local collections for the time being. It’s wonderful; how did I ever live without it?! I use the Albahari brothers’ book “C# 3.0 in a Nutshell” to learn from and for reference. It lives by my side along with Crockford: The Good Parts.
Having a LINQ-friendly XML DOM parser makes sense, so I’m currently learning the X-DOM too.)
Ah, @Andrew beat me to it but you missed the globalization problem entirely here. In general, you want the representation of your data to be culture-insensitive as long as possible, the globalization being applied from the UI. This is why you want the wire format to be culture-neutral, like the tick count we use in our hacky little format and have strong globalization support in the client library (for both formatting and parsing). One of the strengths of Microsoft ajax really, by the way… What other library supports non-Gregorian calendars for example? ;)
Most of my comments echo those already said. Namely the issues of culture and class serialization.
I think I tried the ticks trick once but isn’t the offset different? Or maybe I’m confusing that with the offset in SQL server. Either way, my tick count trick was failing somewhere between browser, server and SQL.
I never considered the RegEx option before and I was going to give that a try until I came across Bret’s mention of jmsajax. I’ve just pulled down a copy and I’m going to experiment with that. It might just be the best overall solution — Thanks Bret.
Just to summarize: Dave Ward solution is only good for non-international applications (I might be mistaken…)
Otherwise,
1. Transfer over the wire (both in && out) culture invariant format, something like {“d”:”\/Date(1240718400000)\/”}
2. Take care of formatting on the client site (to take care cultural variation)
There is a jmsajax plugin(jQuery Microsoft Ajax) to do the job.
X. Another approach will be to detect (if it ever/always possible) a client cultural setting on server side and perform appropriate formatting. I guess, this not a good approach for various reasons.
Am I missing something?
P.S. Did we have very same problem between M$ SQL server & client ~10 year ago? ;-)
Speaking for myself, I’ve never really felt good about client-side localization. The server-side is always going to be more robust, and prevents burdening your client-side payload/code with anything unnecessary.
In the vast majority of cases, being unable to instantiate a JavaScript Date() is a non-issue. It’s not a very common requirement in most real-world apps.
In those few scenarios, it absolutely does make sense to do things the way ASP.NET AJAX does.
Bertrand is right about ASP.NET AJAX’s localization features being very strong too, if you do find yourself needing client-side localization.
Dave,
Agreed… Out of the curiosity – in MVC (and beyond ;-) do you consider “localization stuff” be a part of View or Model (i.e. Business logic)
Beware of “poisoned questions”… You were warned! ;-)
My opinion is that localization shouldn’t be part of the view. How far you push it toward the model probably should depend on whether or not localized strings are actually stored in the database (ergo, part of the model).
I’m no MVC guru though. That’d be a good question for Phil, Rob, or one of the Scotts.
>I’m no MVC guru though.
Never saw one – ‘Quandoque bonus dormitat Homerus’
>That’d be a good question for Phil, Rob, or one of the Scotts.
I’ll get them one day! ;-)
If you’re going to only display the dates, and do all parsing on the server that might work, but that pretty much means that you’re doing AJAH and that you don’t use the client as anything more than a dumb display terminal. In other words, you’re doing UpdatePanel/partial rendering, not really Ajax.
I think you’re very wrong about real Ajax apps being the exception but maybe I misunderstood.
This definitely isn’t an AJAH implementation, for example: http://encosia.com/2008/07/23/sneak-peak-aspnet-ajax-4-client-side-templating/
All I can speak from is my own experience, but I find that I almost never need the proper Date() in practice. You’re rarely comparing dates on the client or performing arithmetic on them. Usually, it’s just a display{/edit/save} scenario with dates, where you specifically want the formatted string anyway.
Dave,
You’re rarely comparing dates on the client or performing arithmetic on them
IMO, you need to change title than:
“How I handle JSON dates returned by ASP.NET AJAX if I don’t need to validate, compare or performing any arithmetic on them on the client!” ;-)
Specifically about validation – server has “no clue” what date formatting a client use.
Even if a client in France, its locale set to French, it might use American date format still and a server have no way of knowing it (IMO!). Therefore you can only to do all above on client AND exchange dates in invariant format only. (IMO again)
Some countries use comma as decimal separator – once a server decide to format numbers nicely – it can lead to very similar problems.
Bottom line – localization is tricky beast – you never know where it’s going to bite you next time. ;-)
I don’t know how to handle it [in all cases]
Didn’t mean to offend anybody – sorry if I did…
Sorting, filtering and grouping? Displaying a date picker that actually understands the human-readable value in the textbox? I could go on.
Would you argue that numbers should be sent as localized strings as well? Of course, JSON fully supports numbers so the problem seems different, but only because there are no date literals in JavaScript, not because there is something fundamentally different that warrants transmitting a localized format for one and not the other. In both cases, I believe that the wire format should be culture neutral.
I think you might be painting yourself into a corner: what will happen when you realize you need the date on the client after all?
Plugins like tablesorter will sort date strings, without needing the Date() object.
For a date picker, I use jQuery UI. To initialize it to a particular date from a short date string, it’s as simple as this:
You can’t do that from a long date string, but when would you ever use a long date string in an edit field anyway? That’s a usability nightmare.
I absolutely agree that Date() objects are sometimes necessary. I’m not at all saying there’s no value in having the option to return the underlying DateTime data. I just don’t find value in using them by default since they require more effort to deal with on the client-side.
In that 5-10% of cases that I do need a Date(), it’s easy enough to switch the return type to DateTime and apply the regex on the client-side. It doesn’t make sense to me to do the extra work for all of the other 90% though.
So, I return strings by default.
Again, this fails with localized dates. Do tablesorter and jQuery UI’s date picker handle localized dates? And who talked about a long date string? You did, not me. A date does not need to be long to be localized. Which date is this: 2/4/2009? For me it’s second of April, for you it’s probably fourth of February.
I’m not saying that it doesn’t work for you, I’m sure it does and if you feel the refactor to make it work the right way is not a lot of work, good for you, but maybe you shouldn’t push people to do the same or at least give them a more complete picture so they know what the limits are. Peace.
This is definitely just what has worked well for me. I’m not trying to force anyone to do something they don’t agree with!
Dave,
“Beware of “poisoned questions”… You were warned! ;-)”
I told you, didn’t I?
May I suggest switching subject?
I would really love to see an example of getting XML dataset and perform XSLT to get [X]HML!
I’m pretty sure – it could be done just in few lines of code – “nice and fluffy” – aka “Dave Ward style”? ;-)
Thx for this very nice post, very informative, as usual!
could not agree more with the “just don’t create a javascript Date object” approach!