我只在需要通过一些测试时才说它,
这是我已经写过的一个:
(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.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 需要登录才能查看:
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 或移动 safari 触发并转移到 ES6 实现时,我认为这个实现应该与它一起使用,而 ES5.1 则占少数。我读过这在 5.1 版的“勘误表”中列出,但我还没有找到。我更认为现在在 ES6 上扣动扳机还为时过早,但我也认为代码需要实用,不理想,并转移到浏览器制造商转移的地方。也就是说,现在似乎是一个 50/50 的决定,所以下面是这段代码的“未来”版本......
我还应该提到,任何一个版本的代码都会规范“不兼容”浏览器以匹配另一个版本的行为,因为这就是 shims 所做的;)
这是一个与 ECMAScript-262 v6.0(JavaScript 未来)兼容的改编版本
在此处查看相关部分:(这是我能找到的唯一在线 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