49 votes

JavaScript: quels navigateurs prennent en charge l'analyse de la chaîne de date ISO-8601 avec Date.parse

J'ai omis d'analyser la date ISO-8601 "2011-04-26T13: 16: 50Z" sur IE8 et Safari 5, mais cela fonctionnait sous Chrome 10, FF4. Le support semble être assez mélangé?

Est-ce que quelqu'un sait où en sont les navigateurs qui peuvent analyser ce format? Je suppose que IE6 et 7 échoueront aussi.

 var d = Date.parse("2011-04-26T13:16:50Z");
 

33voto

ckozl Points 4838

Je dis cale uniquement si besoin par quelques tests,

ici est celle que j'ai déjà écrit:

(function() {

var d = window.Date,
    regexIso8601 = /^(\d{4}|\+\d{6})(?:-(\d{2})(?:-(\d{2})(?:T(\d{2}):(\d{2}):(\d{2})\.(\d{1,3})(?:Z|([\-+])(\d{2}):(\d{2}))?)?)?)?$/;

if (d.parse('2011-11-29T15:52:30.5') !== 1322581950500 ||
    d.parse('2011-11-29T15:52:30.52') !== 1322581950520 ||
    d.parse('2011-11-29T15:52:18.867') !== 1322581938867 ||
    d.parse('2011-11-29T15:52:18.867Z') !== 1322581938867 ||
    d.parse('2011-11-29T15:52:18.867-03:30') !== 1322594538867 ||
    d.parse('2011-11-29') !== 1322524800000 ||
    d.parse('2011-11') !== 1320105600000 ||
    d.parse('2011') !== 1293840000000) {

    d.__parse = d.parse;

    d.parse = function(v) {

        var m = regexIso8601.exec(v);

        if (m) {
            return Date.UTC(
                m[1],
                (m[2] || 1) - 1,
                m[3] || 1,
                m[4] - (m[8] ? m[8] + m[9] : 0) || 0,
                m[5] - (m[8] ? m[8] + m[10] : 0) || 0,
                m[6] || 0,
                ((m[7] || 0) + '00').substr(0, 3)
            );
        }

        return d.__parse.apply(this, arguments);

    };
}

d.__fromString = d.fromString;

d.fromString = function(v) {

    if (!d.__fromString || regexIso8601.test(v)) {
        return new d(d.parse(v));
    }

    return d.__fromString.apply(this, arguments);
};

})();

et dans votre code, il suffit de toujours utiliser Date.fromString(...) au lieu de new Date(...)

test d'un navigateur pour voir si la cale sera utilisé:

http://jsbin.com/efivib/1/edit

fonctionne dans tous les principaux navigateurs, utilisé ces références:

http://dev.w3.org/html5/spec/common-microsyntaxes.html

http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.15

http://msdn.microsoft.com/en-us/library/windows/apps/ff743760(v=vs. 94).aspx

http://msdn.microsoft.com/en-us/library/windows/apps/wz6stk2z(v=vs. 94).aspx

http://msdn.microsoft.com/en-us/library/windows/apps/k4w173wk(v=vs. 94).aspx

!- microsoft connect nécessite un identifiez-vous pour voir:

IE9 n'était pas sur ms, avec un chiffre compte d'autres de 3: (résolu dans IE10) https://connect.microsoft.com/IE/feedback/details/723740/date-parse-and-new-date-fail-on-valid-formats

IE10 est toujours (en 1/17/2013) à défaut lorsque le fuseau horaire est omis (selon l'ECMA, cela devrait defalt à Z ou UTC, pas en local): https://connect.microsoft.com/IE/feedback/details/776783/date-parse-and-new-date-fail-on-valid-formats

-- Lisez ceci si vous vous souciez de où la norme est maintenant / aller dans le futur et pourquoi je ne peux pas obtenir l'équipe IE de reconnaître que leurs IE10 mise en œuvre est techniquement incorrect:

ECMAScript-262 v6.0 va passer à un peu plus iso8601 conformes à la version de "si l'indicateur de fuseau horaire est omis, supposons heure locale"... alors maintenant, il ya un écart, cette mise en œuvre, le chrome, le navigateur safari mobile et opera tous suivre ECMAScript-262 v5.1, tandis que IE10, firefox, bureau safari semblent tous être à la suite de la plus iso8601 conforme ECMAScript-262 v6.0 spécification... ceci est source de confusion pour dire le moins. Lorsque google chrome ou le navigateur safari mobile tirer sur la gâchette et de passer à l'ES6 mise en œuvre, je pense que cette application devrait aller avec elle en laissant ES5.1 dans la minorité. J'ai lu que ceci est indiqué dans les "errata" de la version 5.1 bien que je n'ai pas trouvé. Je suis plus de l'avis que c'est un peu tôt pour tirer sur la gâchette sur l'ES6, mais je suis aussi d'avis que le code doit être pratique, pas l'idéal et de la déplacer à l'endroit où le navigateur décideurs déplacer. Cela dit, il semble être un 50/50 décision maintenant, ci-dessous est le "futur" version de ce code...

Je devrais aussi mentionner que soit la version du code de normaliser "non-conforme" navigateurs pour correspondre au comportement de l'autre, puisque c'est ce que les cales faire ;)

VOICI UNE VERSION ADAPTÉE COMPATIBLE AVEC ECMAScript-262 v6.0 (JavaScript Avenir)

voir les sections pertinentes ici: (c'est le seul en ligne de la version html de la spec que j'ai pu trouver) http://people.mozilla.org/~jorendorff/es6-projet.html#sec-15.9.1.15

(function() {

    var d = window.Date,
        regexIso8601 = /^(\d{4}|\+\d{6})(?:-(\d{2})(?:-(\d{2})(?:T(\d{2}):(\d{2}):(\d{2})\.(\d{1,})(Z|([\-+])(\d{2}):(\d{2}))?)?)?)?$/,
        lOff, lHrs, lMin;

    if (d.parse('2011-11-29T15:52:30.5') !== 1322599950500 ||
        d.parse('2011-11-29T15:52:30.52') !== 1322599950520 ||
        d.parse('2011-11-29T15:52:18.867') !== 1322599938867 ||
        d.parse('2011-11-29T15:52:18.867Z') !== 1322581938867 ||
        d.parse('2011-11-29T15:52:18.867-03:30') !== 1322594538867 ||
        d.parse('2011-11-29') !== 1322524800000 ||
        d.parse('2011-11') !== 1320105600000 ||
        d.parse('2011') !== 1293840000000) {

        d.__parse = d.parse;

        lOff = -(new Date().getTimezoneOffset());
        lHrs = Math.floor(lOff / 60);
        lMin = lOff % 60;

        d.parse = function(v) {

            var m = regexIso8601.exec(v);

            if (m) {
                return Date.UTC(
                    m[1],
                    (m[2] || 1) - 1,
                    m[3] || 1,
                    m[4] - (m[8] ? m[9] ? m[9] + m[10] : 0 : lHrs) || 0,
                    m[5] - (m[8] ? m[9] ? m[9] + m[11] : 0 : lMin) || 0,
                    m[6] || 0,
                    ((m[7] || 0) + '00').substr(0, 3)
                );
            }

            return d.__parse.apply(this, arguments);

        };
    }

    d.__fromString = d.fromString;

    d.fromString = function(v) {

        if (!d.__fromString || regexIso8601.test(v)) {
            return new d(d.parse(v));
        }

        return d.__fromString.apply(this, arguments);
    };

})();

espérons que cela aide -ck

18voto

asgeo1 Points 3336

J'ai eu ce problème aujourd'hui. J’ai trouvé que momentjs était un bon moyen d’analyser les dates ISO 8601 dans un manoir multi-navigateurs.

momentjs peut également être utilisé pour afficher la date dans un format différent.

18voto

Alex Tsurika Points 69

Fonction simple pour analyser le format de date ISO8601 dans n’importe quel navigateur:

 function dateFromISO8601(isoDateString) {
  var parts = isoDateString.match(/\d+/g);
  var isoTime = Date.UTC(parts[0], parts[1] - 1, parts[2], parts[3], parts[4], parts[5]);
  var isoDate = new Date(isoTime);

  return isoDate;
}
 

6voto

Vik David Points 1242

Oui, Date.parse n'est pas cohérent pour différents navigateurs. Vous pourriez:

4voto

kennebec Points 33886

Certains navigateurs plus anciens renvoient la mauvaise date (et non NaN) si vous analysez une chaîne de date ISO.

Vous pouvez utiliser votre propre méthode sur tous les navigateurs ou utiliser Date.parse si elle est implémentée correctement. Vérifiez un horodatage connu.

 Date.fromISO= (function(){
    var diso= Date.parse('2011-04-26T13:16:50Z');
    if(diso=== 1303823810000) return function(s){
        return new Date(Date.parse(s));
    }
    else return 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/).map(function(itm){
                return parseInt(itm, 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;
    }
})()
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X