Andreas
Andreas

Reputation: 2075

JSON Date without eval?

Short description:

Is there a javascript JSON-converter out there that is able to preserve Dates and does not use eval? Example:

var obj1 = { someInt: 1, someDate: new Date(1388361600000) };
var obj2 = parseJSON(toJSON(obj1));
//obj2.someDate should now be of type Date and not String
//(like in ordinary json-parsers).

Long description:

I think most people working with JSON already had the problem of how to transmit a Date:

var obj = { someInt: 1, someDate: new Date(1388361600000) }

When converting this to JSON and back, the date suddenly became a String:

JSON.parse(JSON.stringify(obj)) 
== { someInt: 1, someDate: "2013-12-30T00:00:00.000Z" }

This is a huge disadvantage since you cannot easily submit a Date using JSON. There is always some post-processing necessary (and you need to know where to look for the dates).

Then Microsoft found a loophole in the specification of JSON and - by convention - encodes a date as follows:

{"someInt":1,"someDate":"\/Date(1388361600000)\/"}

The brilliance in this is that there is a now a definitive way to tell a String from a Date inside a valid JSON-string: An encoded String will never contain the substring @"/" (a backslash followed by a slash, not to be confused with an escaped slash). Thus a parser that knows this convention can now safely create the Date-object.

If a parser does not know this convention, the date will just be parsed to the harmless and readable String "/Date(1388361600000)/".

The huge drawback is that there seems to be no parser that can read this without using eval. Microsoft proposes the following way to read this:

var obj = eval("(" + s.replace(/\"\\\/Date\((\d+)\)\\\/\"/g, function (match, time) { return "new Date(" + time + ")"; }) + ")");

This works like a charm: You never have to care about Dates in JSON anymore. But it uses the very unsafe eval-method.

Do you know any ready-to-use-parser that achieves the same result without using eval?

EDIT There was some confusion in the comments about the advantages of the tweaked encoding. I set up a jsFiddle that should make the intentions clear: http://jsfiddle.net/AJheH/

Upvotes: 1

Views: 1030

Answers (2)

symcbean
symcbean

Reputation: 48357

I disagree with adeno's comment that JSON is a notation for strings and cannot represent objects. Json is a notation for compound data types which must be in the form of a serialized objects, albeit that the primitive types can only be integer, float, string or bool. (update: if you've ever had deal with spaghetti coded XML, then you'll appreciate that maybe this is a good thing too!)

Presumably hungarian notation has lost favour with Microsoft if they now think that creating a non-standard notation incorporating the data type to describe a type is better idea.

Of itself 'eval' is not evil - it makes solving some problems a lot easier - but it's very difficult to implement good security while using it. Indeed it's disabled by default with a Content Security Policy.

IMHO it boils down to storing the date as 1388361600000 or "2013-12-30T00:00:00.000Z". IMHO the latter has significantly more semantic value - taken out of context it is clearly a date+time while the latter could be just about anything. Both can be parsed by the ECMAscript Date object without resorting to using eval. Yes this does require code to process the data - but what can you do with an sort of data without parsing it? he only time I can see this as being an advanage is with a schemaless database - but in fairness this is a BIG problem.

Upvotes: 1

Marko
Marko

Reputation: 2734

The issue is the following line of code, here is an example function and take a look at parseWithDate function, add the script to the page and change the following line to this it will work.

http://www.asp.net/ajaxlibrary/jquery_webforms_serialize_dates_to_json.ashx

var parsed1 = JSON.parse(s1); // changed to below
var parsed1 = JSON.parseWithDate(s1);

Updated jsFiddle that works http://jsfiddle.net/GLb67/1/

Upvotes: 0

Related Questions