JavaScript: какие браузеры поддерживают разбор строки даты ISO-8601 с помощью Date.parse



4 Answers

Я говорю, что он подталкивает его только при необходимости через несколько тестов,

вот я уже написал:

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

})();

и в вашем коде просто всегда используйте Date.fromString(...) вместо new Date(...)

проверьте браузер, чтобы увидеть, будет ли использоваться прокладка:

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

работает во всех основных браузерах, использовал эти ссылки:

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 требуется вход в систему для просмотра:

Ошибка IE9 в миллисекундах с цифрами, отличными от 3: (исправлено в IE10) https://connect.microsoft.com/IE/feedback/details/723740/date-parse-and-new-date-fail-on-valid-formats

IE10 по-прежнему (по состоянию на 1/17/2013) не работает, когда часовой пояс не указан (согласно ECMA, это должно деформироваться на Z или UTC, а не локально): https://connect.microsoft.com/IE/feedback/details/776783/date-parse-and-new-date-fail-on-valid-formats

- Прочтите это, если вам небезразлично, где сейчас находится стандарт, и почему я не могу заставить команду IE признать, что их реализация IE10 технически неверна:

ECMAScript-262 v6.0 собирается перейти к чуть более совместимой с iso8601 версии «если индикатор часового пояса опущен, предположим местное время» ... так что теперь есть несоответствие, эта реализация, хром, сафари для мобильных устройств и опера все следуйте ECMAScript-262 v5.1, в то время как IE9, firefox, desktop safari все, похоже, следуют за большей совместимостью с ECOAScript-262 v6.0, совместимой с iso8601 ... это сбивает с толку как минимум. Когда хром или мобильное сафари вытащит триггер и перейдут на реализацию ES6, я думаю, что эта реализация должна пойти на это, оставив ES5.1 в меньшинстве. Я читал, что это указано в «errata» версии 5.1, хотя я его не нашел. Я больше придерживаюсь мнения, что пока еще рано запускать спусковой крючок на ES6, но я также считаю, что код должен быть практичным, а не идеальным и двигаться туда, куда переходят разработчики браузеров. Тем не менее, похоже, это решение 50/50 прямо сейчас, поэтому ниже представлена ​​«будущая» версия этого кода ...

Я должен также упомянуть, что любая версия кода будет нормализовать «несоответствующие» браузеры, чтобы соответствовать поведению другого, поскольку это то, что делают прокладки;)

ЗДЕСЬ АДАПТИРОВАННАЯ ВЕРСИЯ, СОВМЕСТИМАЯ С ECMAScript-262 v6.0 (JavaScript Future)

см. соответствующие разделы здесь: (это единственная онлайн-версия html спецификации, которую я мог найти) http://people.mozilla.org/~jorendorff/es6-draft.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);
    };

})();

надеюсь, что это поможет -ck

Question

Мне не удалось проанализировать дату ISO-8601 «2011-04-26T13: 16: 50Z» на IE8 и Safari 5, но она работала на Chrome 10, FF4. Поддержка кажется довольно смешанной?

Кто-нибудь знает, в каком состоянии браузер может анализировать этот формат? Я предполагаю, что IE6, и 7 тоже не сработает.

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



Microsoft Sharepoint 2013 ТАКЖЕ использует другую нотацию, например «2013-04-30T22: 00: 00Z»,

Если вы хотите использовать службы REST из sharepoint 2013 в сочетании с Internet Explorer 8 (IE8), то решение от ckozl НЕ работает. Вы получите NaN

измените строку регулярных выражений TO:

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

это сделает бит микросекунд дополнительным!

cheerio, Лев




Спецификация ES5 отличается от спецификации ISO8601, особенно когда дело касается обработки дат без индикатора / смещения часового пояса. В https://bugs.ecmascript.org/show_bug.cgi?id=112 есть ошибка, описывающая проблему, и похоже, что она будет исправлена ​​в ES6.

В настоящее время я рекомендую посмотреть на https://github.com/csnover/js-iso8601 для кросс-браузерной реализации. Я использую https://github.com/csnover/js-iso8601/tree/lax который не соответствует спецификации ES5, но имеет лучшую совместимость с другими библиотеками сериализации JSON, такими как JSON.NET.




Как упоминалось ранее, в ECMAScript версии 5 были добавлены даты стиля ISO 8601, где реализация не согласована и недоступна во всех браузерах. Существует number доступных экземпляров скриптов, но вы можете просто добавить свой собственный метод Date.parse *.

(function() {
  //ISO-8601 Date Matching
  var reIsoDate = /^(\d{4})-(\d{2})-(\d{2})((T)(\d{2}):(\d{2})(:(\d{2})(\.\d*)?)?)?(Z|[+-]00(\:00)?)?$/;
  Date.parseISO = function(val) {
    var m;

    m = typeof val === 'string' && val.match(reIsoDate);
    if (m) return new Date(Date.UTC(+m[1], +m[2] - 1, +m[3], +m[6] || 0, +m[7] || 0, +m[9] || 0, parseInt((+m[10]) * 1000) || 0));

    return null;
  }

  //MS-Ajax Date Matching
  var reMsAjaxDate = /^\\?\/Date\((\-?\d+)\)\\?\/$/;
  Date.parseAjax = function(val) {
    var m;

    m = typeof val === 'string' && val.match(reMsAjaxDate);
    if (m) return new Date(+m[1]);

    return null;
  }
}();

Я использую вышеуказанный метод для JSON.parse гидратации дат ...

JSON.parse(text, function(key, val) {
  return Date.parseISO(val) || Date.parseAjax(val) || val;
});



Да, Date.parse несовместим для разных браузеров. Ты мог:

  • Вместо этого используйте Date.UTC , который разбивает строку даты на отдельные входы
  • Используйте библиотеку обертки, такую как parseDate jQuery



Related