2012-09-10 31 views
2

我在使用JSON Web Services的HTML5/JavaScript中構建了Windows 8 Metro應用程序(又名「Modern UI Style」或「Windows Store應用程序」),並且遇到以下問題:,其格式應爲我的JSON Web Services序列化Windows 8 Metro的日期JSON.parse反序列化日期類型中的那些日期的方法?如何使用Windows 8將JSON文本反序列化爲日期類型JSON.parse?

我嘗試:

  • 發送使用ISO-8601 format,(JSON.parse返回字符串),
  • 發送日期的日期,如 「/日期(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" 
+0

「Date」不是支持的JSON類型。您需要從字符串中創建一個Date對象。 –

+0

Date的原型有'toJSON'方法。在具有'toJSON'方法的對象上調用'JSON.parse'會導致處理該'toJSON'調用的結果而不是對象本身。在Date對象的情況下,toJSON返回一個字符串(具體來說就是'toISOString'的結果)。 – apsillers

回答

4

這裏就是我得到了一個通用的方法這方面的工作(儘管我寧願找一個格式由Windows 8的JSON.parse方法支持外的開箱):

在服務器上,我用我的序列化字符串:

date1.ToString("s"); 

本使用ISO 8601日期格式,它始終是相同的,無論所使用的區域性或所提供的格式提供程序(see here for more information)。

在客戶端,我指定了一個「齊磊」回調JSON.parse看起來使用正規式的日期,他們將自動轉換爲Date對象。

最後,反序列化的對象將包含實際的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])); 
    } 
}); 

希望這有助於 卡爾

+0

這不起作用。如果該值與正則表達式不匹配,則reviver函數不返回任何內容,因此'JSON.parse'將* always *返回undefined。 – josh3736

+0

不,這可以在Windows 8上運行:JSON.parse僅在返回某些內容時才使用reviver的值。無需像其他平臺一樣隨時返回任何內容([MDN](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/JSON/parse)或[JSON.ORG]( http://www.json.org/js.html)) – canderso

+0

但是,在IE 9或任何其他瀏覽器中不起作用。我沒有IE 10的方便,但如果這在那裏工作,那麼這是IE中的錯誤。爲了安全起見,只需在函數的末尾添加一個「返回值」即可。 – josh3736

2

這是不是一件獨特的Windows 8中的JSON.parse –它的ECMA standard JSON parser的由設計行爲。因此,有(也可能沒有)對日期的「即時支持」。

根據spec,JSON值只能是字符串,數字,布爾值,數組,對象或null不支持日期。(國際海事組織,這是規範的一部分,但這是我們必須忍受的。)

由於沒有日期類型,您的應用程序必須制定如何處理日期自己。處理此問題的最佳方法是將日期作爲ISO 8601字符串(yyyy-MM-dd'T'HH:mm:ss'Z')發送或自時間(1970年1月1日00:00:00 UTC)以毫秒爲單位發送。這裏的重要部分是確保時間是UTC。

如果性能很重要,我會而不是使用reviver回調與JSON.parseI did a lot of testing,以及爲對象中的每個屬性調用函數所涉及的開銷將性能減半

另一方面,我真的很驚訝測試一個正則表達式對每個字符串值的反應如何,只對已知屬性名稱進行解析。只要確保你定義了一次正則表達式,以外的循環

顯然,將JSON值轉換爲日期的絕對最快的方法是如果您確切知道需要爲日期解析哪些屬性。但是,鑑於基於正則表達式的搜索方法的出色性能,我認爲除非您真的需要額外的性能,否則它不值得額外的複雜性。

有關使用ISO字符串的注意事項與時代以來的毫秒數:獨立測試,milliseconds wins。在IE中,沒有什麼區別,但Firefox確實似乎與ISO字符串有關。另請注意,Date構造函數在所有瀏覽器中都需要幾毫秒。它也採用ISO字符串,但不在IE中≤ 8.

+0

感謝您的輸入。我沒有把正則表達式從循環中取出(因爲我爲了兼容性而向reviver添加了一個返回值)。說到正則表達式,下面是使用ISO 8601格式+ Z:*/^(\ d {4}) - (\ d {2}) - (\ d {2})T(\ d {2})的正則表達式:(\ d {2}):(\ d {2}(?:?\ \ d *))Z $/*。關於瀏覽器和演出,在這種情況下,它是一個Windows 8應用程序,而不是一個網頁,所以我不必看多個瀏覽器的兼容性和性能;) – canderso

相關問題