javascript 日期时区问题

javascript Date timezone issue

我需要一个带有指定日期和年份值的 js Date 对象。我希望 new Date("2000-01-01") 给我 Date 对象,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 getter 并没有真正帮助。

将字符串解析为 JavaScript 中的 Date 时,YYYY-MM-DD 格式的值被解释为 UTC 值,而不是本地时间值。

关键是各个部分之间用连字符隔开,字符串中没有时区信息。 ECMAScript 5.1 规范在 §15.9.1.15:

中说

... The value of an absent time zone offset is “Z”.

这意味着,如果您不指定偏移量,它会假定您指的是 UTC。

请注意,由于这与 ISO-8601 所说的相反,因此 ECMAScript 2015 (6.0) 中的行为已更改,在 §20.3.1.16:

中说明

... If the time zone offset is absent, the date-time is interpreted as a local time.

因此,当 ES6 的这一规定得到正确实施时,以前被解释为 UTC 的这种格式的字符串值将被解释为本地时间。我已经写了关于这个的博客 here

解决方法很简单。用斜杠替换连字符:

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.prototype',并使用它来获取将包括本地时区偏移量的日期。

  //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

通过这种方式,无论您身在何处,都可以“绕过”时区偏移