如何解析JSON以在JavaScript中接收Date对象?

Pio*_*iak 106 javascript datetime json

我有一段JSON:

\/Date(1293034567877)\/
Run Code Online (Sandbox Code Playgroud)

这是.NET代码的结果:

var obj = DateTime.Now;
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
serializer.Serialize(obj).Dump();
Run Code Online (Sandbox Code Playgroud)

现在我面临的问题是如何在JavaScript中创建一个Date对象.我所能找到的是令人难以置信的正则表达式解决方案(许多包含错误).

很难相信没有优雅的解决方案,因为这完全在JavaScrip中,我的意思是JavaScript代码试图读取JSON(JavaScript Object Notation),这应该是一个JavaScript代码,而且此时它证明它不是因为JavaScript不能在这做得很好

我也看到了一些我无法工作的eval解决方案(除了被指出为安全威胁).

难道没有办法优雅地做到这一点吗?

类似的问题没有真正的答案:
如何使用GWT解析ASP.NET JSON日期格式

小智 120

JSON.parse函数接受可选的DateTime reviver函数.你可以使用这样的函数:

dateTimeReviver = function (key, value) {
    var a;
    if (typeof value === 'string') {
        a = /\/Date\((\d*)\)\//.exec(value);
        if (a) {
            return new Date(+a[1]);
        }
    }
    return value;
}
Run Code Online (Sandbox Code Playgroud)

然后打电话

JSON.parse(somejsonstring, dateTimeReviver);
Run Code Online (Sandbox Code Playgroud)

你的约会对应了

  • 我不得不像这样/\/ Date \(( - ?\ d*)\)\ //修改正则表达式,以便它也能够处理负数.当您有一个非常旧的DateTime(在Epoch之前)由.NET转换为JSON时,会出现负数. (7认同)
  • 这种在基本类型(字符串)中编码非原始类型数据的做法是疯狂的.使用有意义的属性在JSON对象中编码日期,或者更进一步,在JSON对象中包含"$ type"属性,以便parse/deserialize例程可以适当地恢复类型,如果要打包所有,甚至可以使用自定义转换器将信息转换为单个属性值,如"ticks"或"ms_since_epoch". (5认同)
  • 为什么不使用`a = Date.parse(value)`而不是`/\/Date\((\d*)\)\//.exec(value);`? (2认同)

Jac*_*cob 47

日期没有标准的JSON表示.你应该做@jAndy建议的事情而不是序列化一个人DateTime; 只需发送一个RFC 1123日期字符串ToString("r")或一个从Unix开始的纪元数字,或者您可以在JavaScript中使用的其他内容来构建一个Date.

  • 现在有一个标准的 JSON 日期格式。https://tools.ietf.org/html/rfc7493#section-4.3 (4认同)
  • 谢谢我走了一条死路,你是第一个指出JSON不支持Date类型的人. (3认同)
  • JSON支持数字,字符串,对象,数组以及文字true,false和null.由于Date不是那些,它是一个复杂的类型,应该存储为一个对象,而不是一个字符串,所以你可以包含类型信息,如特殊成员中的类型名称,如"$ type",永远不会解析为真实对象成员.此类元成员可用于稍后将JSON对象恢复为强类型的运行时对象.我认为在字符串中粘贴日期的做法是愚蠢的,因为它不必要地创建保留字符串模式并尝试在每个字符串上匹配它们. (3认同)

tre*_*ace 46

这个答案来自Roy Tinker:

var date = new Date(parseInt(jsonDate.substr(6)));
Run Code Online (Sandbox Code Playgroud)

正如他所说:substr函数取出"/ Date("部分,而parseInt函数获取整数并忽略最后的")/".生成的数字将传递到Date构造函数中.

另一个选择是在ASP端简单地格式化您的信息,以便JavaScript可以轻松读取它.考虑为您的日期做这件事:

DateTime.Now()
Run Code Online (Sandbox Code Playgroud)

哪个应该返回这样的格式:

7/22/2008 12:11:04 PM
Run Code Online (Sandbox Code Playgroud)

如果你将它传递给这样的JavaScript Date构造函数:

var date = new Date('7/22/2008 12:11:04 PM');
Run Code Online (Sandbox Code Playgroud)

变量date现在保存此值:

Tue Jul 22 2008 12:11:04 GMT-0700 (Pacific Daylight Time)
Run Code Online (Sandbox Code Playgroud)

当然,您可以将此DateTime对象格式化为JS Date构造函数接受的任何类型的字符串/ int .

  • 永远不要依赖于默认的日期< - >字符串转换格式.使用自Epoch以来的毫秒(保留在数字类型域中),更加简单可靠. (4认同)
  • 这个答案提出了两个解决方案 - 第一个是正确的(parseInt),第二个是错误的,所以不确定是投票还是投票!简单地输出为字符串的问题是,如果服务器位于一个国家(例如美国)和另一个国家(例如英国)中的浏览器,则日期可以轻松地向后翻转. (2认同)

Lee*_*Gee 19

如果您在JSON中使用JavaScript样式ISO8601日期,则可以从MDN使用此日期

var jsonDate = (new Date()).toJSON();
var backToDate = new Date(jsonDate);
console.log(jsonDate); //2015-10-26T07:46:36.611Z
Run Code Online (Sandbox Code Playgroud)

  • imo这是最优雅的答案,应该是被接受的答案. (2认同)

Psy*_*nic 6

有什么不对:

new Date(1293034567877);
Run Code Online (Sandbox Code Playgroud)

这对我来说是"2010年12月22日格林尼治标准时间+格林威治标准时间+格林威治标准时间+格林威治标准时间00:16

或者你需要从json中获取数字吗?

  • 我责怪.NET生成一个日期对象的序列化,格式与`\/Date(1293034567877)\ /`一样奇怪.如果它是理智的,它只会输出纪元时间,你可以初始化一个Date对象. (7认同)
  • 你的解决方案有什么问题?那么1293034567877不是我的JSON,对吧?此外,我不需要从JSON中获取数字,我需要将日期输出JSON.我期待从JavaScript获得更多,而不仅仅是能够使用正则表达式.我需要我的代码可读,而不是卡通诅咒. (3认同)
  • @treeface:如果JSON不是JavaScript,那么我认为教程和书籍应该归咎于这种常见的误解.无论如何,我很乐意立刻纠正,真的.至于你的建议,Date可以表示为String我可以说一切都可以表示为String,对吧?但这不会让我们的工作更容易,但非常痛苦和地狱般的.我想我的问题源于这样一个事实:我认为JSON是一种序列化格式(广告宣传以减少带宽并使用JavaScript比使用XML更好).事实证明它不是,至少不是一个无痛的. (2认同)

ViP*_*uL5 6

您可以在JavaScript中将JSON日期转换为正常日期格式.

var date = new Date(parseInt(jsonDate.substr(6)));
Run Code Online (Sandbox Code Playgroud)