2012-06-13 47 views
40

我解析從JSON事件飼料的日期 - 但日期顯示 「南」,在IE7/8:在IE7/IE8的JavaScript JSON日期解析返回NaN

// Variable from JSON feed (using JQuery's $.getJSON) 
var start_time = '2012-06-24T17:00:00-07:00'; 

// How I'm currently extracting the Month & Day 
var d = new Date(start_time); 
var month = d.getMonth(); 
var day = d.getDate(); 

document.write(month+'/'+day);// "6/24" in most browsers, "Nan/Nan" in IE7/8 

我在做什麼錯?謝謝!

+7

它在IE7/8中不受支持。從時代或墊片開始使用毫秒。 – Esailija

+2

我強烈推薦在這裏使用DateJS ... –

+0

另請參見:[哪些瀏覽器支持使用Date.parse解析ISO-8601 Date String?](http://stackoverflow.com/questions/5802461/javascript-which-browsers -support-parsing-of-iso-8601-date-string-with-date-par) –

回答

67

在舊版瀏覽器中,您可以編寫一個函數來爲您解析字符串。

這個創建一個Date.fromISO方法 - 如果瀏覽器本身可以從ISO字符串中獲取正確的日期,則使用本地方法。

一些瀏覽器部分正確,但返回了錯誤的時區,因此只檢查NaN可能不會。

填充工具:

(function(){ 
    var D= new Date('2011-06-02T09:34:29+02:00'); 
    if(!D || +D!== 1307000069000){ 
     Date.fromISO= function(s){ 
      var day, tz, 
      rx=/^(\d{4}\-\d\d\-\d\d([tT ][\d:\.]*)?)([zZ]|([+\-])(\d\d):(\d\d))?$/, 
      p= rx.exec(s) || []; 
      if(p[1]){ 
       day= p[1].split(/\D/); 
       for(var i= 0, L= day.length; i<L; i++){ 
        day[i]= parseInt(day[i], 10) || 0; 
       }; 
       day[1]-= 1; 
       day= new Date(Date.UTC.apply(Date, day)); 
       if(!day.getDate()) return NaN; 
       if(p[5]){ 
        tz= (parseInt(p[5], 10)*60); 
        if(p[6]) tz+= parseInt(p[6], 10); 
        if(p[4]== '+') tz*= -1; 
        if(tz) day.setUTCMinutes(day.getUTCMinutes()+ tz); 
       } 
       return day; 
      } 
      return NaN; 
     } 
    } 
    else{ 
     Date.fromISO= function(s){ 
      return new Date(s); 
     } 
    } 
})() 

結果:

var start_time = '2012-06-24T17:00:00-07:00'; 
var d = Date.fromISO(start_time); 
var month = d.getMonth(); 
var day = d.getDate(); 

alert(++month+' '+day); // returns months from 1-12 
+3

感謝你的救星。 –

+0

這是返回5/24在IE8而不是6/24請你更新功能正常工作? – segFault

+0

沒有更改函數,只是++在警報中增加了date.getMonth()以返回基於1的月份。 – kennebec

25

對於IE7/8我只是做:

var ds = yourdatestring; 
ds = ds.replace(/-/g, '/'); 
ds = ds.replace('T', ' '); 
ds = ds.replace(/(\+[0-9]{2})(\:)([0-9]{2}$)/, ' UTC\$1\$3'); 
date = new Date(ds); 

這將替換所有的 「 - 」 和 「/」,帶有空格的時間標記「T」,並用易於使用IE的字符串替換時區信息,該字符串使IE7/8能夠解析來自字符串的日期corr ectly。爲我解決了所有問題。

+1

不,它會返回不同的日期實例。在Chrome和IE8中比較'new Date('2013/01/01')'。 正確的是'new Date('2013-01-01Z)'(注意Z末尾)。 –

+0

在我以前的帖子中提到「對於ie7/8」。 – fbtb

+1

你說得對,'Z'只在Chrome中使用斜槓時很重要,對不起。 我們只是在所有瀏覽器中用斜槓替換破折號以避免瀏覽器檢測。所以我們需要'Z'。 –

3

對於跨瀏覽器日期問題,我建議http://momentjs.com/

+0

moment.js是一個不錯的選擇。我的問題是規模,它的大部分圍繞致力於處理我不關心的事情。 (例如日期時間戳中的希伯來字符) –

5

請參閱RobG的帖子Result of toJSON() on a date is different between IE8 and IE9+

下面的函數在IE 8及以下版本中爲我工作。

// parse ISO format date like 2013-05-06T22:00:00.000Z 
function convertDateFromISO(s) { 
    s = s.split(/\D/); 
    return new Date(Date.UTC(s[0], --s[1]||'', s[2]||'', s[3]||'', s[4]||'', s[5]||'', s[6]||'')) 
} 

您可以測試象下面這樣:

var currentTime = new Date(convertDateFromISO('2013-05-06T22:00:00.000Z')).getTime(); 
alert(currentTime); 
+1

擡頭,這對於問題中格式化的日期不起作用。你必須使用'00.000Z'格式來表示時間戳,問題中的'-07:00'不會起作用。 –

+1

@breckenedge,你是對的。它必須使用ISO格式'00.000Z' –

+0

我怎樣才能得到經絡(上午或下午)使用convertDateFromISO()方法? –

1

@gib感謝您的Moment.js建議。這個小型圖書館真的幫助處理日期和JavaScript。

Moment.js解決了我原來的問題中描述的問題。當解析成新的Date()對象時,IE8將JSON ISO日期顯示爲NaN。

快速解決方案(包括moment.js在您的網頁,或將代碼複製到你的JS功能包括)

如果你只需要在您的網頁上的日期,從JSON ISO日期加載,做這樣的:

order_date = moment(data.OrderDate); //create a "moment" variable, from the "data" object in your JSON function in Protoype or jQuery, etc. 

$('#divOrderDate).html(order_date.calendar()); //use Moment's relative date function to display "today", "yesterday", etc. 

order_date = moment(data.OrderDate); //create a "moment" variable, from the "data" object in your JSON function in Protoype or jQuery, etc. 

$('#divOrderDate).html(order_date.format('m/d/YYYY')); //use Moment's format function to display "2/6/2015" or "10/19/2014", etc. 

如果你必須有一個日期()對象(說與jQu使用ery組件),請按照以下步驟成功填充JSON提供的ISO日期。 (假設你已經處理了處理你的JSON數據的功能。)

var ship_date = new Date(moment(data.ShipDate).format('m/d/YYYY')); //This will successfully parse the ISO date into JavaScript's Date() object working perfectly in FF, Chrome, and IE8. 

//initialize your Calendar component with the "ship_date" variable, and you won't see NaN again.