Javascript 如何使用Windows 8 JSON.parse将JSON文本反序列化为日期类型?
我正在用HTML5/JavaScript构建一个使用JSON Web服务的Windows 8 Metro应用程序(又名“现代UI风格”或“Windows应用商店应用程序”),我遇到了以下问题:我的JSON Web服务应该以何种格式序列化Windows 8 Metro JSON.parse方法的日期,以反序列化日期类型中的日期? 我试过:Javascript 如何使用Windows 8 JSON.parse将JSON文本反序列化为日期类型?,javascript,json,windows-8,Javascript,Json,Windows 8,我正在用HTML5/JavaScript构建一个使用JSON Web服务的Windows 8 Metro应用程序(又名“现代UI风格”或“Windows应用商店应用程序”),我遇到了以下问题:我的JSON Web服务应该以何种格式序列化Windows 8 Metro JSON.parse方法的日期,以反序列化日期类型中的日期? 我试过: 使用(JSON.parse返回字符串)发送日期 发送日期,例如“/Date(1198908717056)/”作为(相同的结果) 我开始怀疑Windows 8
- 使用(JSON.parse返回字符串)发送日期
- 发送日期,例如“/Date(1198908717056)/”作为(相同的结果)
var d = new Date(); // => a new date
var str = JSON.stringify(d); // str is a string => "\"2012-07-10T14:44:00.000Z\""
var date2 = JSON.parse(str); // date2 is a string => "2012-07-10T14:44:00.000Z"
下面是我如何以一种通用的方式实现这一点的(尽管我更希望找到一种Windows 8的JSON.parse方法支持的开箱即用的格式): 在服务器上,我正在使用以下命令序列化字符串:
date1.ToString("s");
这将使用ISO 8601日期格式,无论使用何种区域性或提供的格式提供程序(),该格式始终相同
在客户端,我为JSON.parse指定了一个“reviver”回调,它使用regexp查找日期并自动将其转换为日期对象
最后,反序列化对象将包含实际的JavaScript日期类型,而不是字符串
下面是一个代码示例:
var responseResult = JSON.parse(request.responseText, function dateReviver(key, value) {
if (typeof value === 'string') {
var re = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)$/
var result = re.exec(value);
if (result) {
return new Date(Date.UTC(+result[1], +result[2] - 1, +result[3], +result[4],+result[5], +result[6]));
}
});
希望这有帮助,
Carl这并不是Windows8的
JSON.parse所独有的特性,它是。因此,对日期没有(也可能没有)现成的支持
根据,JSON值只能是字符串、数字、布尔值、数组、对象或null
不支持日期。(在我看来,这是规范部分的疏忽,但这是我们必须接受的。)
由于没有日期类型,您的应用程序必须自行解决如何处理日期。处理此问题的最佳方法是以ISO 8601字符串(yyyy-MM-dd'T'HH:MM:ss'Z')或以自纪元(1970年1月1日00:00:00 UTC)起的毫秒形式发送日期。这里的重要部分是确保时间以UTC为单位
如果性能很重要,我将而不是使用带有JSON.parse
的恢复器回调,为对象中的每个属性调用函数所涉及的开销将性能削减一半
另一方面,我真的很惊讶,针对每个字符串值测试一个正则表达式能够很好地抵抗只解析已知的属性名。只需确保在循环之外定义一次正则表达式
显然,将JSON值转换为日期的最快方法是如果您确切知道需要为日期解析哪些属性。然而,考虑到基于正则表达式的搜索方法令人惊讶的良好性能,我认为不值得付出额外的复杂性,除非您真的需要额外的性能
关于使用ISO字符串与自epoch以来的毫秒数的说明:独立测试。在IE中,这并没有区别,但Firefox似乎真的很难处理ISO字符串。还要注意,在所有浏览器中,Date
构造函数都需要毫秒。它还需要一个ISO字符串,但不在IE中≤ 8.“日期”不是受支持的JSON类型。您需要从字符串创建一个日期对象。Date
的原型有一个toJSON
方法。对具有toJSON
方法的对象调用JSON.parse
会导致处理该toJSON
调用的结果,而不是处理对象本身。对于Date
对象,toJSON
返回一个字符串(特别是toISOString
的结果)。这不起作用。如果值与正则表达式不匹配,则reviver函数不会返回任何内容,因此JSON.parse
将始终返回未定义的值。不,这在Windows 8上有效:JSON.parse仅在返回某个值时才使用reviver的值。不需要像在其他平台上一样一直返回某些内容(或者仍然返回),在IE9或任何其他浏览器中都不起作用。我手头没有IE 10,但如果它确实在那里起作用,那么它就是IE中的一个bug。为了安全起见,只需在函数末尾添加一个返回值
。是的,要使此代码可移植,必须有一个返回值,但它不是网页,而是Windows 8应用程序,并且此页面永远不会由浏览器呈现。但是,感谢您的输入,如果此代码被复制/粘贴到网页上,我确实添加了一个返回值。我想我的观点是,您的应用程序是由浏览器(IE 10)呈现的,而且由于此行为不符合规范,很可能将来的版本会修复此错误,从而破坏您的代码。感谢您的输入。我确实将regexp从循环中去掉了(因为为了兼容性,我向恢复程序添加了一个返回值)。谈到regexp,这里是使用ISO8601格式+Z://^(\d{4})-(d{2})-(d{2})T(\d{2}):(\d{2}):(\d{2}):(\d{2}(?\.\d)→Z$/*。关于浏览器和性能,在本例中,它是Windows 8应用程序,而不是网页,因此我不必观看多浏览器兼容性和性能;)