2010-02-07 32 views
17

我有这样的代码在一个HTML页面:在我的网页差异日期值JSON.stringify在不同的浏览器

alert(JSON.stringify(new Date())); 

我包括最新json2.js(2009-09-29版本)支持没有JSON.stringify()的旧版浏览器。我也有jquery-1.3.2.js包括在内。我相信新的浏览器具有本机JSON支持,它只是传递给本机JSON功能。

这里的结果我得到了不同的浏览器:

IE 8 on Windows XP: "2010-02-07T21:39:32Z" 
Chrome 4.0 on Windows XP: "2010-02-07T21:39:59Z" 
Firefox 3.0 of Windows XP: "2010-02-07T21:40:41Z" 
Chrome 4.0 on Ubuntu linux: "2010-02-07T21:41:49Z" 
Firefox 3.0 on Ubuntu linux: "2010-02-07T21:42:44Z" 
Chrome 4.0 on Mac OSX: "2010-02-07T21:43:56Z" 
Safari on Mac OSX: "2010-02-07T21:45:21Z" 
Firefox 3.5 on Mac OSX: "2010-02-07T21:44:10.101Z" 

通知的最后一个?它包含毫秒,其他都没有。我没有在任何其他系统上安装FF3.5,但我假设他们会有相同的结果。

有什么我可以做的,使所有平台上的所有日期stringify相同?我的后端REST服务可以配置一个格式字符串来反序列化JSON日期,但它不能支持多种格式,只有一种。

+1

FWIW,我只是测试FF 3.6 Win7上,它也给毫秒。 –

+2

Mozilla邮件列表上的相关帖子:https://mail.mozilla.org/pipermail/es5-discuss/2008-October/001989.html –

+0

哇,他们在几年前以这种方式实现了它?!我很惊讶这并没有造成更多的问题。我很欣赏试图成为符合标准的标准,但如果其他所有事情都以另一种方式进行,至少要给出一个备选方案的配置选项。 – Tauren

回答

9

我得到这个工作将下面的JavaScript:

// Added to make dates format to ISO8601 
Date.prototype.toJSON = function (key) { 
    function f(n) { 
     // Format integers to have at least two digits. 
     return n < 10 ? '0' + n : n; 
    } 

    return this.getUTCFullYear() + '-' + 
     f(this.getUTCMonth() + 1) + '-' + 
     f(this.getUTCDate())  + 'T' + 
     f(this.getUTCHours())  + ':' + 
     f(this.getUTCMinutes()) + ':' + 
     f(this.getUTCSeconds()) + '.' + 
     f(this.getUTCMilliseconds()) + 'Z'; 
}; 

我敢肯定,这可能会减慢序列化,但它似乎使事情在浏览器中保持一致。

0

为什么不在DateQuery的jQuery-UI插件中使用jQuery-UI插件中的formatDate函数来生成服务器端需要的格式?

+0

我传递一个包含日期的对象数组。这意味着要遍历整个数组,并用它们的字符串表示替换Date对象。我希望不必将现有的数组(由第三方工具生成)复制到我自己的版本中,并使用日期字符串。但是,这可能是我需要做的。感谢您的建议! – Tauren

+3

'formatDate'不是一个jQuery函数。看起来是日期选择器控件的一部分。 –

4

您还可以调整json2.js以便始终使用它自己的Date.prototype.toJSON而不是可能的本地值。在这里,我注释掉两行,它工作正常:

// if (typeof Date.prototype.toJSON !== 'function') { 

    Date.prototype.toJSON = function (key) { 

     return isFinite(this.valueOf()) ? 
       this.getUTCFullYear() + '-' + 
      f(this.getUTCMonth() + 1) + '-' + 
      f(this.getUTCDate())  + 'T' + 
      f(this.getUTCHours())  + ':' + 
      f(this.getUTCMinutes()) + ':' + 
      f(this.getUTCSeconds()) + 'Z' : null; 
    }; 

    String.prototype.toJSON = 
    Number.prototype.toJSON = 
    Boolean.prototype.toJSON = function (key) { 
     return this.valueOf(); 
    }; 
// } 
+1

哈哈!我只是在5秒后发布了完全相同的东西......如果您只想定制日期,我不认为需要添加字符串,数字和布尔原型。 – Tauren

3

// 你可能要考虑催谷服务器, 承认任何有效的ISO 8601时间格式:

'2010-02-08T03:37:34.327Z'

“2010- 02-08T03:38:06Z '

'2010-02-08T03:38 + 01:00'

'2010-02-08T03:34:18-05:00'

' 2010 -02- 08T03:34Z”

'2010-02-08'

这是任何异字符串转换为一个JavaScript日期对象的方法。 它可以在服务器上使用一个小翻译:

Date.from_iso= function(s){ 
    var D, M= [], hm, min= 0, d2, 
    Rx= /([\d:]+)(\.\d+)?(Z|(([+\-])(\d\d):(\d\d))?)?$/; 
    D= s.substring(0, 10).split('-'); 
    if(s.length> 11){ 
     M= s.substring(11).match(Rx) || []; 
     if(M[1]) D= D.concat(M[1].split(':')); 
     if(M[2]) D.push(Math.round(M[2]*1000));// msec 
    } 
    for(var i= 0, L= D.length; i<L; i++){ 
     D[i]= parseInt(D[i], 10); 
    } 
    D[1]-= 1; 
    while(D.length< 6) D.push(0); 
    if(M[4]){ 
     min= parseInt(M[6])*60+ parseInt(M[7], 10);// timezone not UTC 
     if(M[5]== '+') min*= -1; 
    } 
    try{ 
     d2= Date.fromUTCArray(D); 
     if(min) d2.setUTCMinutes(d2.getUTCMinutes()+ min); 
    } 
    catch(er){ 
     // bad input 
    } 
    return d2; 
} 
Date.fromUTCArray= function(A){ 
    var D= new Date; 
    while(A.length < 7) A.push(0); 
    var T= A.splice(3, A.length); 
    D.setUTCFullYear.apply(D, A); 
    D.setUTCHours.apply(D, T); 
    return D; 
} 
+0

感谢您的代码,它可能会派上用场。我想我可以使用Joda Time来解析服务器端的不同ISO格式。我使用Jersey和Jackson JSON处理在Java服务器中执行REST。默认情况下,它尝试从几种不同的格式转换,但不幸的是只有其中一个我需要。它有一种方法来覆盖格式,但只有一个格式字符串。我确信有一种方法可以深入并更好地覆盖它,但我必须花更多的时间来做到这一点。 – Tauren