为什么此方法使用UTC时区(Z
)而不包括本地时间偏移量(+/-HH:SS
)? " ISO"在方法名称refers到ISO 8601中 - 允许"time zone designations"表示为其格式的一部分。
换句话说,new Date()
告诉我日期和时间以及时区偏移(通过getTimezoneOffset()
)。但是toISOString()
只告诉我一个时区中的日期和时间 - 它会丢弃new Date()
发起的语言环境中的时间信息。
toISOString()
还包括原始时区与UTC的偏移量是否有意义? toISOString()
省略+/- HH:SS如果用于序列化,则会丢失有关原始 Date
的信息。
我的所有AJAX调用(Angular,jQuery)都通过toISOString()
序列化,因此在与服务器通信时会丢失序列化日期的本地时间。有任何方法可以让JavaScript Date
输出一个ISO格式的字符串,其中还包含偏移量(除了使用像Moment.js这样的库),还是我需要编写自己的方法?
答案 0 :(得分:4)
这是其中之一“因为这是语言规范所说的”答案(见ECMA-262 §20.3.4.36)。 ISO 8601是一种格式,虽然它允许使用时区数据,但ECMAScript仅使用UTC。如果您愿意,可以使用自己的 toLocalISOString 方法扩展 Date.prototype 。顺便说一句,写这样的方法并不困难。
// Format date as ISO 8601 long format with local timezone offset
if (!Date.prototype.toLocalISOString) {
Date.prototype.toLocalISOString = function() {
// Helper for padding
function pad(n, len) {
return ('000' + n).slice(-len);
}
// If not called on a Date instance, or timevalue is NaN, return undefined
if (isNaN(this) || Object.prototype.toString.call(this) != '[object Date]') return;
// Otherwise, return an ISO format string with the current system timezone offset
var d = this;
var os = d.getTimezoneOffset();
var sign = (os > 0? '-' : '+');
os = Math.abs(os);
return pad(d.getFullYear(), 4) + '-' +
pad(d.getMonth() + 1, 2) + '-' +
pad(d.getDate(), 2) +
'T' +
pad(d.getHours(), 2) + ':' +
pad(d.getMinutes(), 2) + ':' +
pad(d.getSeconds(), 2) + '.' +
pad(d.getMilliseconds(), 3) +
// Note sign of ECMASCript offsets are opposite to ISO 8601
sign +
pad(os/60 | 0, 2) + ':' +
pad(os%60, 2);
}
}
document.write(new Date().toLocalISOString())
基于post by DanDascalescu,这里有一个替代方案可能更有效,因为它有更少的函数调用,但它创建了两个额外的Date对象:
// Return a string in ISO 8601 extended format with the host timezone offset
Date.prototype.toLocalISOString = function() {
// If not called on a Date instance, or timevalue is NaN, return undefined
if (isNaN(this) || Object.prototype.toString.call(this) != '[object Date]') return;
// Copy date so don't modify original
var d = new Date(+this);
var offset = d.getTimezoneOffset();
var offSign = offset > 0? '-' : '+';
offset = Math.abs(offset);
var tz = offSign + ('0' + (offset/60|0)).slice(-2) + ':' + ('0' + offset%60).slice(-2)
return new Date(d.setMinutes(d.getMinutes() - d.getTimezoneOffset())).toISOString().slice(0,-1) + tz;
}
console.log(new Date().toLocalISOString())