反序列化客户端AJAX JSON日期
给定以下JSON Date表示形式:
"\/Date(1221644506800-0700)\/"
我们如何将其反序列化为JavaScript Date类型的形式?
我尝试使用MS AJAX JavaScrioptSerializer,如下所示:
Sys.Serialization.JavaScriptSerializer.deserialize("\/Date(1221644506800-0700)\/")
但是,我得到的只是文字字符串日期。
解决方案
回答
最大的数字是标准的JS时间
new Date(1221644506800)
2008年9月17日星期三19:41:46 GMT + 1000(EST)
回答
JSON值是字符串,数字,对象,数组,true,false或者null。所以这只是一个字符串。没有官方的方式来表示JSON中的日期。此语法来自asp.net ajax实现。其他人使用ISO 8601格式。
我们可以这样解析:
var s = "\/Date(1221644506800-0700)\/"; var m = s.match(/^\/Date\((\d+)([-+]\d\d)(\d\d)\)\/$/); var date = null; if (m) date = new Date(1*m[1] + 3600000*m[2] + 60000*m[3]);
回答
ASP.net AJAX反序列化方法中使用的正则表达式将查找类似于" / Date(1234)/"的字符串(该字符串本身实际上需要包含引号和斜杠)。要获得这样的字符串,我们需要转义引号和反斜杠字符,因此用于创建字符串的javascript代码看起来像" " \ / Date(1234)\ / \""。
这将起作用。
Sys.Serialization.JavaScriptSerializer.deserialize("\"\/Date(1221644506800)\/\"")
有点奇怪,但是我发现我必须序列化一个日期,然后序列化从该日期返回的字符串,然后一次在客户端进行反序列化。
这样的事情。
Script.Serialization.JavaScriptSerializer jss = new Script.Serialization.JavaScriptSerializer(); string script = string.Format("alert(Sys.Serialization.JavaScriptSerializer.deserialize({0}));", jss.Serialize(jss.Serialize(DateTime.Now))); Page.ClientScript.RegisterStartupScript(this.GetType(), "ClientScript", script, true);
回答
如果我们知道该字符串绝对是我更喜欢这样做的日期,请执行以下操作:
new Date(parseInt(value.replace("/Date(", "").replace(")/",""), 10))
回答
对于那些不想使用Microsoft Ajax的人,只需将原型函数添加到字符串类。
例如。
String.prototype.dateFromJSON = function () { return eval(this.replace(/\/Date\((\d+)\)\//gi, "new Date()")); };
不想使用eval?试试简单的东西
var date = new Date(parseInt(jsonDate.substr(6)));
作为附带说明,我曾经认为Microsoft通过使用这种格式会产生误导。但是,关于定义JSON中描述日期的方式时,JSON规范并不十分清楚。
回答
从事ASP.NET Atlas / AJAX工作的Bertrand LeRoy描述了JavaScriptSerializer DateTime输出的设计,并揭示了神秘的前斜杠和后斜杠的起源。他提出了以下建议:
run a simple search for "\/Date((\d+))\/" and replace with "new Date()" before the eval (but after validation)
我实现为:
var serializedDateTime = "\/Date(1271389496563)\/"; document.writeln("Serialized: " + serializedDateTime + "<br />"); var toDateRe = new RegExp("^/Date\((\d+)\)/$"); function toDate(s) { if (!s) { return null; } var constructor = s.replace(toDateRe, "new Date()"); if (constructor == s) { throw 'Invalid serialized DateTime value: "' + s + '"'; } return eval(constructor); } document.writeln("Deserialized: " + toDate(serializedDateTime) + "<br />");
这与许多其他答案非常接近:
- 像Sjoerd Visscher一样使用锚定RegEx-不要忘记^和$。
- 避免在RegEx上使用string.replace和'g'或者'i'选项。 " / Date(1271389496563)// Date(1271389496563)/"根本不起作用。