2010-02-07 75 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