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




invalid js (9)

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, Лев

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

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

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

Как упоминалось ранее, в 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;
});

Простая функция для анализа формата даты ISO8601 в любом браузере:

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

Я нашел ответ ckozl действительно полезным и интересным, но регулярное выражение не идеально и в моем случае это не сработало.

Помимо того, что даты без минут, сек или milisecs не анализируются, спецификация ISO 8501 говорит, что разделители '-' и ':' не являются обязательными, поэтому «2013-12-27» и «20131227» являются действительными. В моем случае это важно, потому что я устанавливаю дату и время сервера в переменной JavaScript из PHP:

var serverDate = new Date(Date.parse("<?php date(DateTime::ISO8601); ?>"));

Этот код генерирует что-то вроде этого:

<script>
var serverDate = new Date(Date.parse("2013-12-27T15:27:34+0100"));
</script>

Важной частью является указатель часового пояса «+0100», где отсутствует символ «:». Хотя Firefox правильно разбирает эту строку, IE (11) терпит неудачу (если добавлен «:», то IE также работает). Головная боль о времени zonetime и спецификациях ECMAScript, описанных ckozl, в моем случае несущественна, потому что PHP всегда добавляет указатель часового пояса.

RegExp, который я использую, вместо этого из ckozl:

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

Имейте в виду, что это регулярное выражение также не является совершенным. ISO 8501 позволяет спецификацию недели (2007-W01-1 по понедельникам, 1 января 2007 г.) или десятичные дроби в часах и минутах (18,50 за 18:30:00 или 18:30 - 18:30). Но они довольно необычны.

PD Этот ответ должен быть, я думаю, комментарием к исходному голосовому ответу, но у меня недостаточно репутации :(


У меня был этот вопрос сегодня. Я нашел, что momentjs - хороший способ разбора дат ISO 8601 в перекрестной обозревателе.

momentjs также могут использоваться для вывода даты в другом формате.


ECMAScript-262 v5 был добавлен формат даты ISO 8601 . Поэтому, если браузер не совместим с v5, вы просто не можете ожидать , что сможете обрабатывать форматы ISO 8601.

Браузеры, не совместимые с v5, могут использовать любые форматы дат конкретной реализации, которые они хотят. Большинство из них, по крайней мере, поддерживают RFC1123 даты RFC822 / RFC1123 . Пример:

var d = Date.parse("Wed, 26 Apr 2011 13:16:50 GMT+0200");

Некоторые старые браузеры возвращают неверную дату (а не NaN), если вы разбираете строку даты ISO.

Вы можете использовать свой собственный метод во всех браузерах или использовать Date.parse, если он выполнен правильно - проверьте известную временную метку.

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

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

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

(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


Если вы работаете в SharePoint 2010 или выше, вы можете использовать

using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
...
string strISODate = SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.Now)






javascript internet-explorer datetime safari