我在使用JSON Web服务的HTML5 / JavaScript中构建了一个Windows 8 Metro应用程序(又名“现代UI风格”或“Windows应用商店应用”),我遇到了以下问题:采用哪种格式我的JSON Web服务是否应序列化Windows 8 Metro JSON.parse 方法的日期以反序列化日期类型中的日期?
我试过了:
我开始怀疑Windows 8的JSON.parse方法是否支持日期,即使解析其自己的JSON.stringify方法的输出也不返回日期类型。
示例:
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"
答案 0 :(得分:4)
以下是我如何以通用的方式工作(虽然我宁愿找到Windows 8的JSON.parse方法支持的开箱即用格式):
在服务器上,我使用:
序列化我的字符串date1.ToString("s");
无论使用何种文化格式或提供的格式提供程序(see here for more information),它都使用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]));
}
});
希望这有帮助, 卡尔
答案 1 :(得分:2)
这不是Windows 8 JSON.parse
所特有的 - 它是ECMA standard JSON parser的设计行为。因此,日期有(并且可能)没有“开箱即用的支持”。
每spec,JSON值只能是String,Number,Boolean,Array,Object或null
。 不支持日期。(IMO,这是对规范的疏忽,但这是我们必须忍受的。)
由于没有日期类型,您的应用必须自行解决如何处理日期的问题。处理此问题的最佳方法是将日期发送为ISO 8601字符串(yyyy-MM-dd'T'HH:mm:ss'Z')或自纪元(1970年1月1日00:00:00 UTC)以来的毫秒数。这里的重要部分是确保时间是UTC。
如果性能很重要,我会不使用JSON.parse
的reviver回调。 I did a lot of testing,为对象中的每个属性调用函数所涉及的开销会将性能减少一半。
另一方面,我真的感到惊讶的是,对每个字符串值测试正则表达式只能解析已知的属性名称。只需确保一次定义正则表达式,在循环外!
显然,将JSON值转换为Dates的绝对最快方法是,如果您确切知道需要为日期解析哪些属性。然而,考虑到基于正则表达式的搜索方法的出色表现,我认为除非你真的需要额外的性能,否则它的额外复杂性是不值得的。
关于使用ISO字符串的说明与epoch之后的毫秒数:独立测试,milliseconds wins。在IE中,没有区别,但Firefox似乎真的很难与ISO字符串。另请注意,Date
构造函数在所有浏览器中都需要几毫秒。它也需要一个ISO字符串,但不是IE≤8。