我需要一个具有指定日期和年份值的js-Date对象。我希望new Date("2000-01-01")
给我一个日期对象,getFullYear()
的值为2000,但如果我的计算机的时间设置设置为芝加哥时区,我得到的是Fri Dec 31 1999 18:00:00 GMT-0600 (CST)
,而对于布宜诺斯艾利斯:Fri Dec 31 1999 22:00:00 GMT-0200 (ARST)
。
有没有一种方法可以创建Date对象,无论用户的机器上设置了什么时区,.getFullYear()
都会返回我们在构造函数中设置的日期?
更新:我需要在另一个库中使用这个Date对象(它调用它的.getFullYear()
方法,所以使用UTC getters并没有真正的帮助。
在JavaScript中将字符串解析为Date
时,YYYY-MM-DD
格式的值被解释为UTC值,而不是本地时间值。
关键是这些部分用连字符分隔,并且字符串中没有时区信息。ECMAScript 5.1规范在§15.9.1.15中规定:
缺少时区偏移量的值为"Z"。
这意味着,如果您没有指定偏移量,它将假定您指的是UTC。
请注意,由于这与ISO-8601所说的相反,因此ECMAScript 2015(6.0)中的行为已经发生了变化,该脚本在§20.3.1.16:中进行了说明
如果没有时区偏移,则将日期时间解释为本地时间。
因此,当ES6的这一规定得到正确实施时,以前被解释为UTC的这种格式的字符串值将被解释为当地时间。我在这里发过博客。
解决方法很简单。用斜线替换连字符:
var s = "2000-01-01";
var dt = new Date(s.replace(/-/g, '/'));
另一个可以接受的变通方法是为日期指定中午时间,而不是午夜时间。这将被解析为本地时间,并且距离足够远,可以避免任何DST冲突。
var s = "2000-01-01";
var dt = new Date(s + "T12:00:00");
或者,考虑像moment.js这样更明智的库。
var s = "2000-01-01";
var dt = moment(s, 'YYYY-MM-DD').toDate();
您可以将新方法写入"Date.protype",并使用它来获取包含本地时区偏移量的日期。
//return the date with depend of Local Time Zone
Date.prototype.getUTCLocalDate = function () {
var target = new Date(this.valueOf());
var offset = target.getTimezoneOffset();
var Y = target.getUTCFullYear();
var M = target.getUTCMonth();
var D = target.getUTCDate();
var h = target.getUTCHours();
var m = target.getUTCMinutes();
var s = target.getUTCSeconds();
return new Date(Date.UTC(Y, M, D, h, m + offset, s));
};
这里有一个小技巧可以帮助某人:
let date = new Date();
console.log(date); // -> Fri May 28 2021 01:04:26 GMT+0200 (Central European Summer Time)
const tzOffsetMin = Math.abs(date.getTimezoneOffset()) // the minutes of the offset timezone
const tzOffsetHour = tzOffsetMin / 60; // timezone offset in hour
console.log(tzOffsetHour); // -> 2
date.setHours(date.getHours() + tzOffsetHour); // sum to date hour the timezoneoffset
const isovalue = date.toISOString();
console.log(isovalue); // -> 2021-05-28T01:04:26.156Z
通过这种方式;"旁路";无论您身在何处,的时区偏移量