Подтвердить что ты не робот

Javascript JSON Date синтаксический анализ в IE7/IE8 возвращает NaN

Я разбираю дату из фида событий JSON, но дата показывает "NaN" в IE7/8:

// Variable from JSON feed (using JQuery $.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

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

4b9b3361

Ответ 1

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

Этот метод создает метод 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

Ответ 2

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

Ответ 3

См. сообщение RobG в Результат 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);

Ответ 4

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

Ответ 5

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

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

Быстрое решение (включите moment.js на вашей странице или скопируйте код в свои js-функции)

Если вам просто нужно отобразить дату на вашей странице, загруженную с даты ISO JSON, сделайте следующее:

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 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 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 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.