Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/474.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript:哪些浏览器支持使用Date.parse解析ISO-8601日期字符串_Javascript_Internet Explorer_Datetime_Safari - Fatal编程技术网

JavaScript:哪些浏览器支持使用Date.parse解析ISO-8601日期字符串

JavaScript:哪些浏览器支持使用Date.parse解析ISO-8601日期字符串,javascript,internet-explorer,datetime,safari,Javascript,Internet Explorer,Datetime,Safari,我未能在IE8和Safari 5上解析ISO-8601日期“2011-04-26T13:16:50Z”,但它在Chrome 10、FF4上有效。支持率似乎参差不齐 有人知道哪些浏览器可以解析这种格式的实际状态吗?我想IE6和IE7也会失败 var d = Date.parse("2011-04-26T13:16:50Z"); 是的,Date.parse对于不同的浏览器不一致。你可以: 改为使用,它将日期字符串拆分为单独的输入 使用包装器库,如 v5中添加了日期格式。因此,如果浏览器与v5不兼

我未能在IE8和Safari 5上解析ISO-8601日期“2011-04-26T13:16:50Z”,但它在Chrome 10、FF4上有效。支持率似乎参差不齐

有人知道哪些浏览器可以解析这种格式的实际状态吗?我想IE6和IE7也会失败

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

是的,Date.parse对于不同的浏览器不一致。你可以:

  • 改为使用,它将日期字符串拆分为单独的输入
  • 使用包装器库,如
v5中添加了日期格式。因此,如果浏览器与v5不兼容,就不能指望能够处理ISO 8601格式

与v5不兼容的浏览器可以使用他们想要的任何特定于实现的日期格式。不过,它们中的大多数至少支持/date格式。例如:

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

如果解析ISO日期字符串,一些旧浏览器会返回错误的日期(而不是NaN)

您可以在所有浏览器中使用自己的方法,或者在正确实现的情况下使用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;
    }
})()

如前所述,ISO 8601样式的日期是在ECMAScript版本5中添加的,该版本的实现不一致,并且并非在所有浏览器中都可用。有一个脚本存根可用,但您可能希望只添加自己的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;
});

我说只有在需要的时候通过一些测试

我已经写了一篇:

(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(…)
而不是
newdate(…)

测试浏览器以查看是否将使用垫片:

适用于所有主要浏览器,使用了以下引用:

!-microsoft connect需要登录才能查看:

IE9以毫秒为单位失败,数字计数不是3:(在IE10中修复)

当时区被省略时,IE10仍然(截至2013年1月17日)失败(根据ECMA,这应该被定义为Z或UTC,而不是本地):

--如果您关心标准现在/将来的发展方向,以及为什么我无法让IE团队认识到他们的IE10实现在技术上是不正确的,请阅读此文:

ECMAScript-262 v6.0将移动到更符合iso8601标准的版本“如果省略时区指示器,则假设本地时间”。。。所以现在有一个差异,这个实现,chrome,mobile safari和opera都遵循ECMAScript-262 v5.1,而IE10,firefox,desktop safari似乎都遵循更符合iso8601的ECMAScript-262 v6.0规范。。。至少可以说,这令人困惑。当chrome或mobile safari触发并转向ES6实现时,我认为这个实现应该与之配套,让ES5.1处于少数。我已经读到,这列在5.1版的“勘误表”中,尽管我还没有找到它。我更倾向于认为现在就启动ES6还为时过早,但我也认为代码需要实用,而不是理想的,并向浏览器制造商的方向发展。这就是说,这似乎是一个50/50的决定,现在,所以下面是这个代码的“未来”版本

我还应该提到,这两个版本的代码都将规范化“不兼容”的浏览器,以匹配另一个版本的行为,因为垫片就是这样做的;)

这是一个与ECMAScript-262 v6.0(JavaScript未来版)兼容的改编版本。

请参阅此处的相关部分:(这是我能找到的规范的唯一在线html版本)


希望这有帮助-ck

ES5规范偏离ISO8601规范,特别是在处理没有时区指示器/偏移的日期时。在描述这个问题时有一个错误提示,看起来它将在ES6中得到修复


目前,我建议您考虑使用跨浏览器实现。我使用的是不符合ES5规范,但与其他JSON序列化库(如JSON.NET)具有更好的互操作性的。我发现这是一种在跨浏览器庄园解析ISO8601日期的好方法


momentjs还可用于以不同格式输出日期。

Microsoft Sharepoint 2013也使用不同的表示法,例如“2013-04-30T22:00:00Z”

如果要将sharepoint 2013中的REST服务与Internet Explorer 8(IE8)结合使用,则ckozl中的解决方案不起作用。 你会得到答案的

将正则表达式行更改为:

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,Leo

在任何浏览器中解析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的答案非常有用和有趣,但是regexp并不完美,在我的例子中也不起作用

除了不解析没有分钟、秒或毫秒的日期之外,ISO 8501规范还规定“-”和“:”分隔符是可选的,因此“2013-12-27”和“20131227”都是有效的。在我的例子中,这一点很重要,因为我在PHP的JavaScript变量中设置服务器日期和时间:

var serverDate = new Date(Date.parse("<?php date(DateTime::ISO8601); ?>"));
请记住,这个regexp也不是完美的。ISO 8501允许使用周规格(2007年1月1日星期一为2007-W01-1),或以小时和分钟为单位的小数(18:30:00为18.50,18:30:15为18:30.25)。但它们很不寻常


p.D.我想,这个答案应该是对原始chozl答案的评论,但我没有足够的声誉:(

可能我们无法找到这个答案,因为ECMAScript-262v5支持没有很好地发布。有用的链接:,这里有一个可以处理更多版本的
rx=/^(\D{4}-\D\D\-\D\D([tT][\D:\.]*)?)([zZ].[++-](\D{3}))?$/,
如下所示:以下
code
var-diso=Date.parse('2012-06-25T22:19:43.4859618Z');if(diso==1340662783485)返回函数{
codevar serverDate = new Date(Date.parse("<?php date(DateTime::ISO8601); ?>"));
<script>
var serverDate = new Date(Date.parse("2013-12-27T15:27:34+0100"));
</script>
var regexIso8601 = /^(\d{4}|\+\d{6})(?:-?(\d{2})(?:-?(\d{2})(?:T(\d{2})(?::?(\d{2})(?::?(\d{2})(?:(?:\.|,)(\d{1,}))?)?)?(Z|([\-+])(\d{2})(?::?(\d{2}))?)?)?)?)?$/;