反序列化客户端AJAX JSON日期

时间:2020-03-05 18:58:34  来源:igfitidea点击:

给定以下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)/"根本不起作用。