Javascript JSON Анализ даты в IE7/IE8 возвращает NaN

Я анализирую дату из фида событий JSON, но в IE7/8 эта дата показывает "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

Что я делаю неправильно? Спасибо!

5 ответов

Решение

В старых браузерах вы можете написать функцию, которая будет анализировать строку для вас.

Этот метод создает метод Date.fromISO - если браузер может изначально получить правильную дату из строки ISO, используется собственный метод.

Некоторые браузеры получили это частично правильно, но вернули неверный часовой пояс, поэтому проверка на наличие NaN может не сработать.

Polyfill:

(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

Для 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 правильно анализировать даты из строк. Решил все вопросы за меня.

Посмотрите сообщение РобГа в Результат toJSON() о дате, отличающейся между IE8 и 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);

Я предлагаю http://momentjs.com/ для кросс-браузерных проблем с датой.

@gib Спасибо за предложение на Moment.js. Эта небольшая библиотека действительно помогает в работе с датами и JavaScript.

Moment.js решил проблему, описанную в оригинальном вопросе, который у меня тоже возник. IE8 отображал даты JSON ISO как NaN при разборе в новый объект Date().

Быстрое решение (включите 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.  

Если у вас должен быть объект Date() (скажем, для использования с компонентами jQuery), выполните следующие действия, чтобы успешно заполнить ваш 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.
Другие вопросы по тегам