Scott Hanselman

On the nightmare that is JSON Dates. Plus, JSON.NET and ASP.NET Web API

March 6, '12 Comments [69] Posted in ASP.NET | Javascript | Open Source
Sponsored By

Ints are easy. Strings are mostly easy. Dates? A nightmare. They always will be. There's different calendars, different formats. Did you know it's 2004 in the Ethiopian Calendar? Yakatit 26, 2004, in fact. I spoke to a German friend once about how much 9/11 affected me and he said, "yes, November 9th was an amazing day in Germany, also."

Dates are hard.

If I take a simple model:

public class Post
{
public int ID { get; set; }

[StringLength(60)][Required]
public string Title { get; set; }

[StringLength(500)]
[DataType(DataType.MultilineText)]
[AllowHtml]
public string Text { get; set; }

public DateTime PublishedAt { get; set; }
}

And I make a quick ASP.NET Web API controller from VS11 Beta (snipped some stuff for simplicity):

public class PostAPIController : ApiController
{
private BlogContext db = new BlogContext();

// GET /api/post
public IEnumerable<Post> Get()
{
return db.Posts.ToList();
}

// GET /api/post/5
public Post Get(int id)
{
return db.Posts.Where(p => p.ID == id).Single();
}
...snip...
}

And hit /api/post with this Knockout View Model and jQuery.

$(function () {
$("#getPosts").click(function () {
// We're using a Knockout model. This clears out the existing posts.
viewModel.posts([]);

$.get('/api/PostAPI', function (data) {
// Update the Knockout model (and thus the UI)
// with the posts received back
// from the Web API call.
viewModel.posts(data);
});
});

viewModel = {
posts: ko.observableArray([])
};

ko.applyBindings(viewModel);
});

And this super basic template:

<li class="comment">
<header>
<div class="info">
<strong><span data-bind="text: Title"></span></strong>
</div>
</header>
<div class="body">
<p data-bind="date: PublishedAt"></p>
<p data-bind="text: Text"></p>
</div>
</li>

I am saddened as the date binding doesn't work, because the date was serialized by default like this. Here's the JSON on the wire.

[{
"ID": 1,
"PublishedAt": "\/Date(1330848000000-0800)\/",
"Text": "Best blog post ever",
"Title": "Magical Title"
}, {
"ID": 2,
"PublishedAt": "\/Date(1320825600000-0800)\/",
"Text": "No, really",
"Title": "You rock"
}]

Eek! My eyes! That's milliseconds since the beginning of the Unix Epoch WITH a TimeZone. So, converting in PowerShell looks like:

PS C:\> (new-object DateTime(1970,1,1,0,0,0,0)).AddMilliseconds(1330848000000).AddHours(-8)

Sunday, March 04, 2012 12:00:00 AM

Yuck. Regardless,  it doesn't bind with KnockoutJS either. I could add a bindingHandler for dates like this:

ko.bindingHandlers.date = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var jsonDate = valueAccessor();
var value = new Date(parseInt(jsonDate.substr(6)));
var ret = value.getMonth() + 1 + "/" + value.getDate() + "/" + value.getFullYear();
element.innerHTML = ret;
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
}
};

That works, but it's horrible and I hate myself. It's lousy parsing and it doesn't even take the TimeZone into consideration. This is a silly format for a date to be in on the wire.

Example of Knockout binding

I was talking to some folks on Twitter in the last few days and said that all this is silly and JSON dates should be ISO 8601, and we should all move on. James Newton-King the author of JSON.NET answered by making ISO 8601 the default in his library. We on the web team will be including JSON.NET as the default JSON Serializer in Web API when it releases, so that'll be nice.

I mentioned this to Raffi from Twitter a few weeks back and he agreeds. He tweeted back to me

He also added "please don't do what the @twitterAPI does (ruby strings)." What does that look like? Well, see for yourself: https://www.twitter.com/statuses/public_timeline.json in a random public timeline tweet...snipped out the boring stuff...

{
"id_str": "176815815037952000",
"user": {
"id": 455349633,
...snip...
"time_zone": null
},
"id": 176815815037952000,
"created_at": "Mon Mar 05 23:45:50 +0000 2012"
}

Yes, so DON'T do it that way. Let's just do it the JavaScript 1.8.5/ECMASCript 5th way and stop talking about it. Here's Firefox, Chrome and IE.

All the browsers support toJSON()

We're going to do this by default in ASP.NET Web API when it releases. (We aren't doing this now in Beta) You can see how to swap out the serializer to JSON.NET on Henrik's blog. You can also check out the Thinktecture.Web.Http convenience methods that bundles some useful methods for ASP.NET Web API.

Today with the Beta, I just need to update my global.asax and swap out the JSON Formatter like this (see Henrik's blog for the full code):

// Create Json.Net formatter serializing DateTime using the ISO 8601 format
JsonSerializerSettings serializerSettings = new JsonSerializerSettings();
serializerSettings.Converters.Add(new IsoDateTimeConverter());
GlobalConfiguration.Configuration.Formatters[0] = new JsonNetFormatter(serializerSettings);

When we ship, none of this will be needed as it should be the default which is much nicer. JSON.NET will be the default serializer AND Web API will use ISO 8601 on the wire as the default date format for JSON APIs.

ISO Dates in Fiddler

Hope this helps.


Sponsor: Big thanks to DevExpress for sponsoring this last week's feed. There is no better time to discover DevExpress. Visual Studio 11 beta is here and DevExpress tools are ready! Experience next generation tools, today.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. I am a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web
Tuesday, March 06, 2012 12:21:02 AM UTC
hmmm, my 1-liner to parse WCF JSON Dates :)

function date(s) { return new Date(parseFloat(/Date\(([^)]+)\)/.exec(s)[1])); }


Taken from my JSON prettifier: http://www.ajaxstack.com/jsonreport/
Tuesday, March 06, 2012 12:24:01 AM UTC
Boy am I glad I saw this post! I just put together a simple (or so I thought) app to try this out and was about to google the goofy date that was returned. You just saved me a lot of time and effort!
Tuesday, March 06, 2012 12:25:43 AM UTC
Actually crap:

new Date(parseInt(jsonDate.substr(6)));

Is much nicer, surprised that works... testing...
Tuesday, March 06, 2012 12:27:24 AM UTC
Great job, Scott. That's the one thing about JSON that I could just never understand how it got that way...
Tuesday, March 06, 2012 12:29:56 AM UTC
@PRMan this provides a good explanation of why JSON dates are the way they are:

http://msdn.microsoft.com/en-us/library/bb299886.aspx
Tuesday, March 06, 2012 12:31:36 AM UTC
Ironically, the posting date for this entry says this hasn't happened for another eight hours.

"March 6, 2012 12:15 AM"

UTC conversion issue? :P
Kevin Clayborn
Tuesday, March 06, 2012 12:34:03 AM UTC
Dates are such a common data type that it seems absurd that JSON didn't bother including this in the standard.

"A value can be a string in double quotes, or a number, or true or false or null, or an object or an array. These structures can be nested." JSON.org


The latest version of Sugar handles the ugly date format from the default ASP.Net JSON serializer, but I really like using a standard date format, especially 8601. Hopefully all the JSON libraries will recognize this format.
Tuesday, March 06, 2012 12:39:35 AM UTC
So, you are introducing a BREAKING CHANGE with this. Just GREAT!!!

I know you may hate the existing datetime format (I do to), but existing sites really rely on that, and this artical on MSDN Stand-Alone JSON Serialization.

Basically, I can't just update to use this instead of the existing api for a few reasons:
1) Breaking the contract - We have told our users that the date has to be in this format
2) We have a strict restriction on using 3rd party libraries, so now you are DEFAULTING to it?? Our legal department will have a fit!
3) This also means you won't be using the DataContractJsonSeralizer anymore? What about WCF? Is it also switching, or do we have issues within our own app (WCF expecting one format, and this giving another).

PLEASE DO NOT set JSON.NET as the default, but make it available, and fix the DataContractJsonSerializer to support more date formats than the \/Date(xxx)\/ one.
Chad
Tuesday, March 06, 2012 12:45:27 AM UTC
This is lousy:

new Date(parseInt(jsonDate.substr(6)));

Don't do this, you are losing your timezone information.

Instead, just remove the \\ and / from the ASPNET string:

"\\/Date(1320825600000-0800)\\/".replace( /[\\/]/g, "")

This gives you:

Date(1320825600000-0800)

To convert this back into a JSON date, you can "new" the object in an eval:

var d = eval ("new " + "\\/Date(1320825600000-0800)\\/".replace( /[\\/]/g, ""))

Tuesday, March 06, 2012 12:50:12 AM UTC
Great news! Sometimes standards really do make things easier, this one especially. Newton-King's JSON.Net really kicks butt too.

Also, I just finally setup a W8 box and played a little with VS11 Beta and the WebAPI. The OS experience is a little disheartening yet, but I'm digging VS and WebAPI a lot... anxious to work with it more.
Tuesday, March 06, 2012 12:51:14 AM UTC
Although the default date format of Json.NET is changing in Json.NET 4.5 (the next major release), there is a an option to continue using the Microsoft format.
Tuesday, March 06, 2012 1:03:22 AM UTC
My concern is the same. If I just upgrade, without making any code changes, it will change the format. This release was SUPPOSED to be an inline update that DID NOT have any breaking changes - THIS IS ONE.

And then, what about, like us, a large corp that can't update everything at once, we have some using the old and some using the new format.

This means, even if we could get by our legal department (they look really hard at the license agreement) that we can NEVER use the new format, as it won't work with the systems that still require the old, unless they update DataContractJsonSerializer with support for more dates.
Chad
Tuesday, March 06, 2012 1:22:23 AM UTC
Normal WCF JSON serialization isn't changing, and Web API is still in beta.

If you want to continue using DataContractJsonSerializer then why not create a MediaTypeFormatter that uses DataContractJsonSerializer? If Microsoft doesn't include one out of the box then I'm sure someone else will make one.

On licensing, Json.NET is the standard MIT license.
Tuesday, March 06, 2012 1:22:39 AM UTC
Chad - You don't use modernizr, Jquery, jqueryUI or any of the other 3rd party libs? This will be supported Open Source just like our existing uses I open source. Want to use a different default? Easy to switch back. Remember that when we include open source, we back it with support. If you call and have a problem with ASP.NET, we will support all of it, including the open source we ship. Does that help? We have been doing that for 3+ years now.

Also, Chad - we are changing only ASP.NET Web API...A product that isn't released. We aren't changing asp.net proper or WCF. Better? There is no breaking change as this is a new product, only now in beta.
Scott Hanselman
Tuesday, March 06, 2012 1:28:28 AM UTC
Presumably, only code that is using the new Web API framework will be using the new JSON.NET and therefore the updated date format.

All of your old code is most likely fine as it wasn't written to target the ApiController.

I don't see how this is a breaking change.
Tuesday, March 06, 2012 1:34:34 AM UTC
@Chad,

I don't think you read the post correctly. This change to the default serializer is happening in the ASP.NET Web API, not .NET. The standalone serializer isn't being removed. This change is only happening between the Web API beta and the final RTM. If your corporation is as large as you say it is, I seriously doubt you have production code deployed on a Web API beta that was only released a couple weeks ago.

TLDR: Nobody moved your cheese. Everything will be okay.
Tuesday, March 06, 2012 1:41:29 AM UTC
OK, so now only the webapi is updated, that is better, but we still won't be able to use it.

I was more making a point about the library (as we already use JSON.NET in some situations.

The problem I see now is one of incompatibility. If you aren't updating WCF, or ASP.NET, dates creating in one won't work in the other. So how do you suggest calling an existing service when you have a DateTime as a property in the serialized object? How do you know what format to put it in?

I know that JSON.NET can handle it, but it requires a special date handler, and DataContractJsonSerializer won't handle the new format. Can there at least be updates to make it EASILY work between services, without having to know what date format it is in.

DateTime.Parse handles several, but not the existing DataContractJsonSerailizer format, and then there is JavascriptSerializer - which is different.

I really like the simplicity of the DataContractJsonSerializer, and have heard several of my coworkers complain about JSON.NET.
Chad
Tuesday, March 06, 2012 1:45:18 AM UTC
@Chad,

In those cases, you can force JSON.NET to use the Microsoft form instead of the 8601 standard as pointed out by James in a comment above.
Tuesday, March 06, 2012 1:45:19 AM UTC
'Bout time- all it takes is a decent critical mass of libraries doing it the same way to get a de facto standard. This has been biting me in the a*s for at least the last 5 years- I'll be more than happy to throw away all that conversion code I've been patching in at various layers.
Tuesday, March 06, 2012 1:45:53 AM UTC
Or you could override the default serializer in the Web API to use the same one you use everywhere else. (Sorry to double post!)
Tuesday, March 06, 2012 2:01:35 AM UTC
Sure, we could, but again, can't we make all of the MS serializers consistant, or at least deserialize both the existing format and 8601 standard?
Chad
Tuesday, March 06, 2012 2:33:57 AM UTC
How can I swap out for JSON.NET in all of ASP.NET?:
- JsonValueProvider for MVC model binding
- JsonResult from an MVC method
- Web API
- asmx services
- etc
Is there a voodoo initialize method(s) that says "just go do it for everything" I can call from Global.asax.cs?
Rob
Tuesday, March 06, 2012 2:46:45 AM UTC
So glad to see this! I just recently ran into this issue with MVC3 JsonResult. Parsing it correctly client-side isn't the end of the world, but it's the little things that make all the difference. I get more excited for VS2011 with the 4.5 Framework and all that's coming with them everyday. Keep up the good work sir!
Tuesday, March 06, 2012 2:51:23 AM UTC
yes, it's a good feature. the format "\/Date(1320825600000-0800)\/" is weird.
Tuesday, March 06, 2012 3:11:10 AM UTC
This is beyond fantastic news. I've been on a couple of projects recently where we were using vanilla MVC as an API endpoint, and the first thing I did was write a model binder to use JSON.NET for all of our serialization needs (because of the way it handles dates and enumerations). So nice to see the wheel not be reinvented.
Tuesday, March 06, 2012 7:26:11 AM UTC
regarding the whole "9-11" thing.

im from south africa and we write our dates normally in the dd-mm-yy format. it makes sense, it goes from smallest, to biggest. i have never understood mm-dd-yy. please explain the logic behind it.. first list the medium one, then the small one, then the big one.

/weirdos




Tuesday, March 06, 2012 7:44:53 AM UTC
I prefer to add one property to model

//your model
public DateTime PublishedAt { get; set; }

//new property
public string PublishedAtString { get{ return PublishedAt.ToShortDateString(); }}

This will display normal in view when passed with knockout and you won't have any problems passing it to controller on POST.

Hope it helps.
Mata
Tuesday, March 06, 2012 8:19:57 AM UTC
I was just about to start solving this problem for my own project. My idea was to use the JavascriptSerializer as Shawn Wildermuth wrote: http://wildermuth.com/2012/2/22/WebAPI_for_the_MVC_Guy. But now I know the direction of WebApi I will follow that and use the approach of Henrik Nielsen and mark my code immediately as obsolete as soon as the next version of WebApi will arive ;-)
Thank for sharing this just in time!
Tuesday, March 06, 2012 9:14:27 AM UTC
Mata - But ToShortDateString is culture sensitive and will serialize with the current culture of the thread. 
Scott Hanselman
Tuesday, March 06, 2012 9:55:21 AM UTC
Just wanted to say: Absolutely brilliant, very glad this is happening.
Tuesday, March 06, 2012 10:25:58 AM UTC
@Scott I know, i'm looking forward to JSON.NET as the default JSON Serializer in Web API too, i just wanted to share my solution when you don't need globalization support (wire format to be culture-neutral). I use this approach and set jqueryui datepicker to choose appropriate locale http://jqueryui.com/demos/datepicker/localization.html . It's not perfect but it works.

Regards, always a pleasure to read your blog.
Mata
Tuesday, March 06, 2012 11:29:44 AM UTC
I completely agree with the adoption of ISO as a stringified date standard.

Thinking I was clever I spent quite some time using the Unix Epoch / 1970 / what is this madness??!! style dates in my own applications. In the end I came to the realisation that having something that can be read and understood by human eyes has real merit and so now I'm sticking with that.

Delighted to hear that this approach looks to be being adopted "officially". Marvellous!
Tuesday, March 06, 2012 11:59:42 AM UTC
JsAction library has a solution too: http://jsaction.codeplex.com/wikipage?title=DateTime&referringTitle=ExplainSource
Vincenzo
Tuesday, March 06, 2012 1:14:31 PM UTC
Return a string and ToString the date with the correct DateTime format pattern.
Tuesday, March 06, 2012 1:16:43 PM UTC
Fantastic news! The very first thing I did when playing with the API was to swap in the JSON.NET formatter.
Tuesday, March 06, 2012 1:27:03 PM UTC
Please what ever you do, don't base it off Microsoft's broken format for IS8601. http://msdn.microsoft.com/en-us/library/system.globalization.datetimeformatinfo.sortabledatetimepattern.aspx

Please make sure that it comes out with millisecond resolution and nothing more, that the time zone is always included. In cases of DateTime please use local machine timezone or UTC timezone of "Z".

This is how dates should be formatted from DateTime and DateTimeOffset.

"yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'"

I can't tell you how much it pains me to see all these different so called ISO formats in the .NET framework that don't really reflect reality.
Tuesday, March 06, 2012 1:28:32 PM UTC
Check out moment.js its a hardcore date parsing/formatting library and friendly to asp.net, I think you will find it solves most of the ugliness you mention in your post. cheers
Tuesday, March 06, 2012 1:46:45 PM UTC
To clarify my comment from above, the only DateTime formatter that follows ISO 8601 is "o". But the industry as a whole, as pretty much settled on millisecond resolution for the DateTime format, mostly because this is the resolution of UNIX time.

It would be great if Microsoft also supported this.

yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffzzz (this is the "o" format, which is ISO 8601)
yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z' (this is the industry standard ISO 8601 format)


It would save me a lot of time trying to create the most usable API across web clients, if Microsoft out of the box just supported this second format.

Thanks
Tuesday, March 06, 2012 1:56:23 PM UTC
This is great news! As a middle tier developer working in the world of REST, this will make the interactions with the UI team just that much easier.
Tuesday, March 06, 2012 3:07:18 PM UTC
@hilton smith: It's because in US English we speak dates as, "March 5, 2012." So 3-5-12 makes sense. But what do we know... we still don't use the metric system.
Tuesday, March 06, 2012 3:36:14 PM UTC
Thanks Scott! the choice of the dateTime format in JSON is really ugly!
I suffered from that nightmare, and decided finally to serialize in ISO 8601 as u did (Glad to do like U :)). but with cost!
Now if you tell me it's gonna be supported in future releases IT'LL BE GREAT!
I loved the "(new Date()).toJSON()" Part :)
Tuesday, March 06, 2012 5:46:34 PM UTC
Yes, dates are really hard. The worst part is that most developers think that because its in the BCL that DateTime is perfect. It's not. There are a few guys trying to do something about it, by re-implementing java's "joda" project as pure .net. Check out Jon Skeet's post about "Noda Time" http://noda-time.blogspot.com

Also, DataContractJsonSerializer is pretty bad with JSON Dates. It completely ignores the offset when deserializing, among other things. http://connect.microsoft.com/VisualStudio/feedback/details/723368

I'm super glad to head about JSON.Net being used for webapi instead. Question - is System.Json a different serializer than DCJS (in System.Runtime.Serialization) If not, why the new namespace?
Tuesday, March 06, 2012 9:07:58 PM UTC
@Nick Berardi

The Json.NET change to use ISO 8061 is available from GitHub now. Right now it follows how .NET writes ISO dates in XML.
Wednesday, March 07, 2012 1:54:52 PM UTC
Hi,

Great post, we actually bumped into similar issues not so long ago. As a consequence we actually coded our own JSON serailizer/deserializer a single and light yet powerful class named JsonUtilities which ends-up supporting three different date formats:
- \/Date(1330848000000-0800)\/, with or without “TZ“ (this is our default, and here's why: http://weblogs.asp.net/bleroy/archive/2008/01/18/dates-and-json.aspx)
- new Date(utc milliseconds)
- ISO 8601

Check-out this blog post if you want to know more: Dates and JSON

Cheers,
Carl
Wednesday, March 07, 2012 3:18:08 PM UTC
Dear Mr. Hanselman,

Are we going to see better odata support in Web API by the time it hits RTM especially for things like $inlinecount, etc that will make it possible to do paging and other stuff using it?

Thanks!
Thursday, March 08, 2012 12:47:16 AM UTC
Vesselin - If you want Web API to be like OData you are better off using OData, I think.
Thursday, March 08, 2012 7:09:04 PM UTC
It seems that if we use this approach, that we are not allowed to have api controller methods that accept multiple parameters, or especially any parameters that are primitive types (int, string). For example, if instead of taking a custom class instance as a parameter, my method takes two strings:

Post(string value1, string value2)

...this json.net formatter chokes on the json you send it (as opposed to when you just use the regular formatter) (say that json is {"value1":"one","value2":"two"} - the original formatter likes this, but the json.net formatter you use here doesn't). It gives this exception: {"ExceptionType":"Newtonsoft.Json.JsonSerializationException","Message":"Cannot deserialize JSON object into type 'System.String'. Line 1, position 12.","StackTrace":" at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader

Any ideas?
Jme1234
Thursday, March 08, 2012 9:27:48 PM UTC
Maybe I don't totally get what the issue on the client is, but if KO cant' handle a json date, that's a KO problem isn't it? That is, the templates aren't designed to handle dates. So if you wanted something that was formatted in a template, then you should pass a string in the first place, I would think. I've never used that before so I am not sure why it would be this way, but I've never had any problems with JS dates on the client. I pass a date from code, it gets serialized into a wierd number, and JSON.parse turns it back into a date at the client.

More annoying is getting back what you started with on the server, here's my solution to that problem. I'm sure it could be shorter.

Changing the way dates are serialized sounds like a recipe for disaster, though, I mean it's not really valid JSON any more.


public static DateTime FromJSDateTime(string jsDateTime)
{
Regex regex = new Regex(@"^""\\/Date\((?<ticks>-?[0-9]+)\)\\/""");
string ticks = regex.Match(jsDateTime).Groups["ticks"].Value;
DateTime dt = unixEpoch.AddMilliseconds(Convert.ToDouble(ticks));
return DateTime.SpecifyKind(dt, DateTimeKind.Utc).ToLocalTime();
}
Thursday, March 08, 2012 11:07:01 PM UTC
I take back part of my previous comment... I forgot that actually *there is no (official) JSON standard for dates* :) But the rationale for using that format (e.g. it's parsable directly by JS and distinguishable from a string) makes some sense, and it's in common use, so changing it still seems risky.

And ultimately why worry about parsing dates at the client if all you were going to do was turn it into a string? C# is much better for formatting strings than javascript!
Friday, March 09, 2012 11:29:08 AM UTC
Web API rocks but the serialization issues would have been a *major* blunder if not fixed by RTM...

Adding Json.net will also help with other big issues like support untyped objects (type object), anonymous types, much better and two-way dictionary serialization, plus the ability to more easily plug in new converters if necessary in an easy way.

Adding Json.net is a great choice, but it's *stunning* to me that Microsoft couldn't get their own JSON serialization fixed with 3 different serialization tools (JavaScriptSerializer, DataContractJsonSerializer and now the new System.Json classes which are woefully incomplete and will compete with Json.net's feature set). Instead we'll have yet another DLL in the assembly soup that WebAPI adds to a project (can we get that consolidated please before RTM please???) and presumably in addition to System.Json which will add more confusion yet over what the right way to do low level JSON manipulation. <sigh> Two steps forward, one step back...
Monday, March 12, 2012 11:51:50 AM UTC
The first thing I was going to do with the Web API is make it play with JSON.NET now I don't have to :) Web API using JSON.NET by default is awesome news thank you.

@Rob I also needed more control over JSON formatting, before I knew about Web API I created a JsonValueProviderFactory using JSON.NET. If you use my JsonValueProviderFactory and create a ActionResult that returns JsonConvert.SerializeObject(myModel); you will have completely swapped out the JavaScriptSerializer from MVC.

http://www.dalsoft.co.uk/blog/index.php/2012/01/10/asp-net-mvc-3-improved-jsonvalueproviderfactory-using-json-net/
Wednesday, March 14, 2012 4:03:51 PM UTC
ISO 8601 date format is also supported in ServiceStack.Text now by set global configuration as:

JsConfig.DateHandler = JsonDateHandler.ISO8601;
Tuesday, March 27, 2012 8:30:52 PM UTC
Scott,

One more pet peeve. Entity Framework returns DateTimes back as DateTimeKind.Unspecified. I save all of my DateTimes to the DB in UTC, but if the JSON serializer sees DateTimeKind.Unspecified, it figures it is local time and again, converts to UTC for a JSON Date(xxxxx) response. The result is double hour shifting!

I wrote a T4 template that forces all retrieved DateTime objects from the DB to come back as DateTimeKind.UTC by default, but a simple config file flag to force EF to return them UTC, built in, would be A-W-E-S-O-M-E.

My blog post on this: http://www.aaroncoleman.net/post/2011/06/16/Forcing-Entity-Framework-to-mark-DateTime-fields-at-UTC.aspx

--Aaron
Thursday, April 05, 2012 8:43:57 AM UTC
You say dates are hard. They are hard indeed but not impossible, try json serializing EF 4.0 entities using webHttpBinding.
Tuesday, April 17, 2012 12:35:25 PM UTC
It all blows - the proposed solution is horrendous as well. What if my string really looks like "2001-01-01T01:01:01Z" - the library is going to grab it and make it a date.

There is nothing wrong with duck typing, but 'suck' typing (portmanteau of string and duck) is just asking for trouble. How do you fix it? The best I can come up with is:

{
"title": "test"
"posted": type.dateTime("2001-01-01T01:01:01Z")
}


This retains the 'jsony' paradigm where if you executed the string you would get the correct object (even though you shouldn't). 'type' would simply be an object passed through with a couple of methods (from what I can tell, only 'dateTime' would actually be needed).
Friday, July 06, 2012 7:52:57 PM UTC
Glad to see that JSON DateTime serialization is becoming more sane. No more ugly parsing!
Thursday, July 26, 2012 8:20:55 AM UTC
Now in RC we get nice js iso dates from the WebAPI, BUT with no timezone information. Why that? How to tell the formatter to always include the timezone?
Tuesday, August 21, 2012 10:35:43 PM UTC
This example works perfectly:

var dataAUX = newcDate(parseInt(data.DataInicio.substr(6)));

var dataEND = dataAUX.getMonth() + 1 + "/" + dataAUX.getDate() + "/" + dataAUX.getFullYear() + " " + dataAUX.getHours() + ":" + dataAUX.getMinutes() + ":" + dataAUX.getSeconds();

This Way You Will get the hours as well
José
Monday, August 27, 2012 8:32:44 PM UTC
I'm looking for a similar fix for WCF Data Services. We have a client running into this, but who has specified MVC3/.NET4 (let me know if I'm confused on technologies here...)
Tuesday, August 28, 2012 2:28:19 PM UTC
For anybody looking for a WCF Data Services solution, StackOverflow landed me on a solution: update to v5 and use oData v3: http://stackoverflow.com/questions/12148692/how-to-properly-handle-json-date-formatting-issues-for-wcf-data-services/12149363#12149363
Thursday, August 30, 2012 6:16:25 PM UTC
Is there a way to control/change the settings on the default JSNO.Net serializer? Or do I have to still do the swap with my own?
Sunday, October 14, 2012 1:04:33 AM UTC
People say I'm crazy to hand write the json but this is a perfect example why.
Mike
Friday, December 14, 2012 9:56:23 PM UTC
Hey Scott, is this an IE9 bug?

http://stackoverflow.com/questions/13886642/json-iso8601-parsing-in-javascript

Tuesday, March 19, 2013 9:01:45 PM UTC
So, did ASP.NET MVC 4 ship with JSON.net as the default formatter? Looking at the wire I still see date times in this format Date(1330848000000-0800)?
Scott Smith
Tuesday, April 02, 2013 7:43:28 PM UTC
Thanks man.! #Useful ..
Wilson Rivera
Monday, May 20, 2013 2:39:41 PM UTC
Link is broken.

https://www.twitter.com/statuses/public_timeline.json
Joe
Friday, May 31, 2013 9:38:59 AM UTC
Doesn't replacing the json serializer bypass MVC's default output sanitizer and therefore potentially expose XSS threats? Make sure you manually sanitize after serialize or include the sanitizing in the serializer!
Mark
Tuesday, June 04, 2013 5:36:22 PM UTC
It's too bad posting a date to MVC causes it to convert it from UTC to local server timezone, which can push the date part into the previous day. The lack of a date type in .NET is another source of nightmares.
AaronLS
Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.