web-dev-qa-db-fra.com

Javascript JSON Date parse dans IE7 / IE8 renvoie NaN

J'analyse une date à partir d'un flux d'événements JSON - mais la date affiche "NaN" dans 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

Qu'est-ce que je fais mal? Merci!

40
Josiah

Dans les anciens navigateurs, vous pouvez écrire une fonction qui analysera la chaîne pour vous.

Celui-ci crée une méthode Date.fromISO - si le navigateur peut nativement obtenir la date correcte à partir d'une chaîne ISO, la méthode native est utilisée.

Certains navigateurs ont partiellement raison, mais ont renvoyé le mauvais fuseau horaire, donc la simple vérification de NaN peut ne pas fonctionner.

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);
        }
    }
})()

Résultat:

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
67
kennebec

Pour ie7/8, je viens de faire:

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);

Cela remplace toutes les occurrences de "-" par "/", le marqueur de temps "T" par un espace et remplace les informations de fuseau horaire par une chaîne compatible avec IE qui permet à IE7/8 d'analyser correctement les dates des chaînes. Résolu tous les problèmes pour moi.

25
fbtb

Voir le billet de RobG à Le résultat de toJSON () à une date est différente entre IE8 et IE9 + .

La fonction ci-dessous a fonctionné pour moi dans IE 8 et ci-dessous.

// 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]||''))
}

Vous pouvez tester comme ci-dessous:

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

Je suggère http://momentjs.com/ pour les problèmes de date entre navigateurs.

3
gib

@gib Merci pour la suggestion sur Moment.js. Cette petite bibliothèque aide vraiment à gérer les dates et JavaScript.

Moment.js a résolu le problème décrit dans la question d'origine que j'avais également. IE8 affichait les dates ISO JSON sous forme de NaN lors de l'analyse dans un nouvel objet Date ().

Solution rapide (incluez moment.js dans votre page, ou copiez le code dans vos fonctions js)

Si vous avez juste besoin d'afficher une date sur votre page, chargée à partir d'une date ISO JSON, faites ceci:

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.

ou

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.  

Si vous devez avoir un objet Date () (par exemple pour une utilisation avec les composants jQuery), procédez comme suit pour remplir avec succès la date ISO fournie par JSON (cela suppose que vous êtes déjà dans la fonction de gestion de vos données 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.
1
William Smith