如何使用Windows 8 JSON.parse将JSON文本反序列化为日期类型?

时间:2012-09-10 15:21:29

标签: javascript json windows-8

我在使用JSON Web服务的HTML5 / JavaScript中构建了一个Windows 8 Metro应用程序(又名“现代UI风格”或“Windows应用商店应用”),我遇到了以下问题:采用哪种格式我的JSON Web服务是否应序列化Windows 8 Metro JSON.parse 方法的日期以反序列化日期类型中的日期?

我试过了:

  • 使用ISO-8601 format发送日期,(JSON.parse返回一个字符串),
  • 发送日期,例如“/ Date(1198908717056)/”为explained here(同样的结果)。

我开始怀疑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"

2 个答案:

答案 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。