我在IE8和Safari 5上无法解析ISO-8601日期"2011-04-26T13:16:50Z",但它在Chrome 10, FF4上工作。支持的声音似乎褒贬不一。
有人知道哪些浏览器可以解析这种格式的实际状态吗?我猜IE6和ie7也会失败。
var d = Date.parse("2011-04-26T13:16:50Z");
我说只有在需要时才能通过一些测试来填充它,
这里有一个我已经写过了:
(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(...)
测试浏览器是否会使用shim:
http://jsbin.com/efivib/1/edit可以在所有主流浏览器中工作,使用这些引用:
http://dev.w3.org/html5/spec/common-microsyntaxes.htmlhttp://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需要登录才能查看:
IE9在数字计数不是3的情况下毫秒失败:(在IE10中修复)https://connect.microsoft.com/IE/feedback/details/723740/date-parse-and-new-date-fail-on-valid-formats
IE10仍然(截至2013年1月17日)在省略时区时失败(根据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标准的版本"如果时区指示符被省略,假设当地时间"…所以现在有一个差异,这个实现,chrome,移动safari和opera都遵循ECMAScript-262 v5.1,而IE10, firefox,桌面safari似乎都遵循更符合iso8601的ECMAScript-262 v6.0规范…这至少可以说是令人困惑的。当chrome或移动浏览器启动ES6实现时,我认为这个实现应该随之而去,让ES5.1成为少数。我读到这是在5.1版本的"勘误表"中列出的,尽管我没有找到它。我更倾向于认为现在就发布ES6还为时过早,但我也认为代码应该是实用的,而不是理想的,应该顺应浏览器制造商的发展方向。也就是说,现在似乎是50/50的决定,所以下面是这个代码的"未来"版本…
我还应该提到,两个版本的代码都将规范"不兼容"的浏览器,以匹配另一个浏览器的行为,因为这就是shims所做的;)
这是一个与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
我今天有这个问题。我发现momentjs是在跨浏览器庄园中解析ISO 8601日期的好方法。
还可以使用momentjs以不同的格式输出日期。
在任何浏览器中解析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;
}
Yes, Date。不同浏览器的Parse不一致。你可以:
- 使用日期。UTC,它将日期字符串分解为单独的输入
- 使用包装器库,如jQuery的parseDate
如果解析ISO日期字符串,一些较旧的浏览器返回错误的日期(而不是NaN)。
你可以在所有浏览器中使用你自己的方法,或者使用Date。解析它是否被正确实现检查已知的时间戳
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}-dd-dd([tT][d:.]*)?)([zZ]|([+-])(dd):(dd))?$/,
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;
}
})()
ES5规范偏离了ISO8601规范,特别是在处理没有时区指示符/偏移量的日期时。在https://bugs.ecmascript.org/show_bug.cgi?id=112上有一个bug票描述了这个问题,看起来它将在ES6中修复。
现在,我建议查看https://github.com/csnover/js-iso8601以获得跨浏览器实现。我使用https://github.com/csnover/js-iso8601/tree/lax,它不符合ES5规范,但与其他JSON序列化库(如JSON.NET)具有更好的互操作性。
我发现ckozl答案非常有用和有趣,但是regexp并不完美,它在我的情况下不起作用。
除了不解析没有分钟、秒或毫秒的日期之外,ISO 8501规范规定'-'和':'分隔符是可选的,因此"2013-12-27"one_answers"20131227"都是有效的。在我的例子中,这很重要,因为我将在PHP的JavaScript变量中设置服务器日期和时间:
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也可以正常工作)。关于时区和ECMAScript规范的头痛在我的例子中并不重要,因为PHP总是添加时区指示符。
我正在使用的RegExp,而不是来自cokozl的RegExp是:
var regexIso8601 = /^(d{4}|+d{6})(?:-?(d{2})(?:-?(d{2})(?:T(d{2})(?::?(d{2})(?::?(d{2})(?:(?:.|,)(d{1,}))?)?)?(Z|([-+])(d{2})(?::?(d{2}))?)?)?)?)?$/;
请记住,这个regexp也不是完美的。ISO 8501允许星期规格(2007- w01 -1适用于星期一,2007年1月1日),或小时和分钟的十进制分数(18:30:00为18.50,18:30:15为18:30.25)。但它们很不寻常。
p。d。我想,这个答案应该是对原始chozl答案的评论,但是我没有足够的信誉:
正如前面提到的,ISO 8601样式日期是在ECMAScript版本5中添加的,它的实现不一致,并且在所有浏览器中都不可用。有许多可用的脚本存根,但您可能希望简单地添加自己的Date。解析*方法。
(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使用上述方法。解析枣的水合作用…
JSON.parse(text, function(key, val) {
return Date.parseISO(val) || Date.parseAjax(val) || val;
});
ISO 8601日期格式在ECMAScript-262 v5中添加。因此,如果浏览器不兼容v5,您就不能期望能够处理ISO 8601格式。
不兼容v5的浏览器可以使用任何特定于实现的日期格式。不过,它们中的大多数至少支持RFC822/RFC1123日期格式。例子:var d = Date.parse("Wed, 26 Apr 2011 13:16:50 GMT+0200");
Microsoft Sharepoint 2013也使用不同的符号,例如"2013-04-30T22:00:00Z"
如果你想使用sharepoint 2013的REST服务与IE8 (Internet Explorer 8)相结合,那么从ckozl的解决方案是不工作的。你会得到NaN
将正则表达式行改为:
regexIso8601 = /^(d{4}|+d{6})(?:-(d{2})(?:-(d{2})(?:T(d{2}):(d{2}):(d{2})(.(d{1,3}))?(?:Z|([-+])(d{2}):(d{2}))?)?)?)?$/;
这将使微秒位可选!
恭喜恭喜,狮子座