反序列化客户端 AJAX JSON 日期

Posted

技术标签:

【中文标题】反序列化客户端 AJAX JSON 日期【英文标题】:Deserializing Client-Side AJAX JSON Dates 【发布时间】:2010-09-10 01:41:44 【问题描述】:

给定以下 JSON 日期表示:

"\/Date(1221644506800-0700)\/"

如何将其反序列化为 javascript 日期类型的形式?

我尝试过使用 MS AJAX JavaScrioptSerializer,如下所示:

Sys.Serialization.JavaScriptSerializer.deserialize("\/Date(1221644506800-0700)\/")

但是,我得到的只是文字字符串日期。

【问题讨论】:

你可能在使用 jQuery 吗?检查我的博客文章以自动转换日期,因此您不必手动进行。 erraticdev.blogspot.com/2010/12/… 见下面我的 cmets。您博客的代码在纪元之前的日期失败。 【参考方案1】:

如果您知道字符串绝对是我更喜欢这样做的日期:

 new Date(parseInt(value.replace("/Date(", "").replace(")/",""), 10))

【讨论】:

这对我有用,我的 ToJson 方法将 DateTimes 序列化为“\/Date(1251795081950)\/” 谢谢。 var date = new Date(parseInt(jsonDate.substr(6))); 也可以。【参考方案2】:

Bertrand LeRoy,曾在 ASP.NET Atlas/AJAX 上工作,described the design of the JavaScriptSerializer DateTime output 并揭示了神秘的前斜线和后斜线的起源。他提出了这个建议:

对“\/Date((\d+))\/”进行简单搜索,并在 eval 之前替换为“new Date($1)” (但经过验证)

我将其实现为:

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($1)");
    if (constructor == s) 
        throw 'Invalid serialized DateTime value: "' + s + '"';
    
    return eval(constructor);


document.writeln("Deserialized: " + toDate(serializedDateTime) + "<br />");

这与许多其他答案非常接近:

像 Sjoerd Visscher 那样使用锚定正则表达式 - 不要忘记 ^ 和 $。 避免使用 string.replace,以及 RegEx 中的“g”或“i”选项。 “/Date(1271389496563)//Date(1271389496563)/”根本不应该工作。

【讨论】:

一个很好的答案....可惜我在问题列表的底部找到它。 该正则表达式不适用于纪元之前的日期,它具有负值。你需要这样的东西:/\/Date\((-?\d+)(?:-\d+)?\)\//i【参考方案3】:

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]);

【讨论】:

我的 toJson 方法将序列化日期吐出为“\/Date(1251795070160)\/”,您的代码无法解析。稍后我会找出原因,只是在这里为其他人发帖 +1 用于明确 JSON 值可以是什么以及日期不是其中之一,而是一种自定义格式。 该正则表达式不适用于纪元之前的日期,它具有负值。你需要这个:/\/Date\((-?\d+)(?:-\d+)?\)\//i @Sjoerd:您必须添加时区还是减去时区才能将其转换为 UTC?我很困惑,因为如果我看到1/1/2000 0:0:0 +0500 的时间(我认为)我必须减去 5 小时才能获得 UTC 时间。 如果没有指定时区,你可以回退到 parseInt if (date == null) date = new Date(parseInt(s.substring(6, s.length - 2), 10));【参考方案4】:

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);

【讨论】:

这个方法的问题是它不看时区:Sys.Serialization.JavaScriptSerializer.deserialize("\"\\/Date(1221644506800+0200)\\/\"" ) 结果与以下相同: Sys.Serialization.JavaScriptSerializer.deserialize("\"\\/Date(1221644506800+0300)\\/\"")【参考方案5】:

对于不想使用微软Ajax的人,只需在字符串类中添加一个原型函数即可。

例如

    String.prototype.dateFromJSON = function () 
    return eval(this.replace(/\/Date\((\d+)\)\//gi, "new Date($1)"));
;

不想使用 eval?尝试一些简单的事情,例如

var date = new Date(parseInt(jsonDate.substr(6)));

顺便说一句,我曾经认为 Microsoft 使用这种格式具有误导性。然而,在定义用 JSON 描述日期的方式时,JSON 规范并不是很清楚。

【讨论】:

该正则表达式不适用于纪元之前的日期,它具有负值。你需要这个:/\/Date\((-?\d+)(?:-\d+)?\)\//i【参考方案6】:

其实momentjs是支持这种格式的,你可以这样做:

    var momentValue = moment(value);

    momentValue.toDate();

这会以 javascript 日期格式返回值

【讨论】:

【参考方案7】:

大的数字是标准的JS时间

new Date(1221644506800)

2008 年 9 月 17 日星期三 19:41:46 GMT+1000(美国东部标准时间)

【讨论】:

以上是关于反序列化客户端 AJAX JSON 日期的主要内容,如果未能解决你的问题,请参考以下文章

如何使用客户端的时区将 asp.net 日期时间反序列化为 JSON 日期时间

将json的日期属性反序列化为LocalDate

反序列化 JSON Google AJAX 翻译 API

spring mvc接收ajax提交的JSON数据,并反序列化为对象

WCF 无法反序列化 JSON 请求

JSON如何反序列化日期时间并将UTC转换为指定时区?