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

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

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

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


person Josiah    schedule 13.06.2012    source источник
comment
он не поддерживается в IE7/8. Используйте мс с эпохи или прокладку.   -  person Esailija    schedule 13.06.2012
comment
Я очень рекомендую использовать DateJS здесь...   -  person Andrew Whitaker    schedule 13.06.2012


Ответы (5)


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

Этот создает метод 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
person kennebec    schedule 13.06.2012
comment
Это возвращает 5/24 в IE8 вместо 6/24. Не могли бы вы обновить функцию, чтобы она работала правильно??? - person segFault; 10.03.2013
comment
Не изменил функцию, просто ++ увеличил date.getMonth() в предупреждении, чтобы вернуть месяц на основе 1. - person kennebec; 10.03.2013
comment
Это прекрасно работает, спасибо. Был бы очень признателен, если бы вы могли немного прокомментировать код, чтобы помочь нам понять, почему вы сделали определенные вещи, например. +Д!==1307000069000 - person jackocnr; 04.06.2013
comment
@jackocnr Это тоже заняло у меня минуту. + преобразует D в число. Если это допустимая дата, она совпадает с D.getTime() или 1307000069000. В противном случае NaN. Не очень читабельно, но умно. - person visum; 07.03.2014
comment
Регулярное выражение должно быть обновлено до: rx=/^(\d{4}\-\d\d\-\d\d([tT ][\d:\.]*)?)([zZ]|( [+\-])(\d\d):?(\d\d))?$/ Добавление знака вопроса после последнего двоеточия, что делает его необязательным. Смещение часового пояса часто не включает двоеточие. (пример: -400, +0000) Это формат PHP для константы DateTime::ISO8601 без двоеточия. - person Nicholas E.; 06.07.2015
comment
таааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааа: - person Szymon; 23.11.2016

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

person fbtb    schedule 24.07.2013
comment
Нет, он вернет разные экземпляры даты. Сравните new Date('2013/01/01') в Chrome и в IE8. Правильным будет new Date('2013-01-01Z) (обратите внимание на Z в конце). - person Dzmitry Lazerka; 28.10.2013
comment
упоминание для ie7/8 в моем предыдущем посте. - person fbtb; 29.10.2013
comment
Вы правы, буква «Z» имеет значение только тогда, когда в Chrome используется косая черта, извините. Мы просто заменяем тире косой чертой во всех браузерах, чтобы избежать обнаружения браузера. Итак, нам нужна буква «Z». - person Dzmitry Lazerka; 19.11.2013
comment
я столкнулся с той же проблемой с IE8, .replace('-', '/') решил проблему. Большое спасибо ! - person Gurpreet Singh; 04.04.2014
comment
Неа. В IE8 это дало мне строку 2015/01/12T08:05:02.68, которую он преобразовал в значение Invalid Date. - person Mike Gledhill; 13.01.2015

См. сообщение 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);
person Estin Chin    schedule 19.09.2014
comment
Обратите внимание, это не работает для даты, отформатированной в вопросе. Вы должны использовать формат 00.000Z для меток времени, -07:00 в вопросе не будет работать. - person Aaron Breckenridge; 15.01.2015
comment
@breckenedge, ты прав. Он должен использовать формат ISO 00.000Z - person Estin Chin; 23.04.2015

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

person gib    schedule 18.10.2013
comment
moment.js — достойный вариант. Моя проблема заключается в размере, так что большая часть его обхвата предназначена для работы с вещами, которые меня не волнуют. (например, еврейские символы в штампах даты и времени) - person The Dembinski; 24.10.2016

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

or

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.
person William Smith    schedule 28.09.2014