覆盖Javascript Date构造函数?

时间:2012-01-19 06:55:10

标签: javascript date

我正在开发一个对当前日期敏感的浏览器应用程序。

在我的应用程序代码中,我调用new Date并根据当前时间执行计算并相应地呈现视图。

为了测试我的应用程序在不同的潜在日历日,我将不得不经常将我的系统时钟更改为过去或将来,这是一个烦恼,可能对我的计算机不健康。

纯粹出于测试目的(我永远不会在生产中使用此代码),我决定通过在控制台中执行此操作来覆盖内置Date构造函数:

// create a date object for this Friday:
var d = new Date(2012, 0, 20)
//override Date constructor so all newly constructed dates return this Friday
Date = function(){return d}

考虑到这个假设,我尝试了这个并得到了奇怪的结果:

var now = new Date
Sat Apr 07 2012 00:00:00 GMT-0400 (EDT)

now = new Date
Tue Jul 10 2012 00:00:00 GMT-0400 (EDT)

now = new Date
Wed Jul 09 2014 00:00:00 GMT-0400 (EDT)

now = new Date
Wed Jun 07 2023 00:00:00 GMT-0400 (EDT)

......依旧......

我的问题是,到底发生了什么?

如果我覆盖构造函数以返回静态日期,为什么它会提供不相关且不断递增的日期?

此外,是否有一种有效的方法可以覆盖Date构造函数以在将来返回静态日期,而无需在代码中进行所有日期实例化调用并修改输出?

提前致谢。

编辑:

我在一个新窗口中尝试了我的代码,它按预期工作。

似乎罪魁祸首是jQuery UI datepicker插件,它调用了它的“刷新”方法。当我禁用它的调用时,日期覆盖正常工作,但是一旦我使用datepicker,就会发生上面的奇怪行为。

不知道为什么这个流行的插件会以某种方式影响这样的全球性事物。如果有人有任何想法,请告诉我。

很抱歉没有弄清楚真正的罪魁祸首。

5 个答案:

答案 0 :(得分:10)

我也遇到了这个问题,最后为此编写了一个模块。也许它对某些人有用:

Github: https://github.com/schickling/timemachine

timemachine.config({
  dateString: 'December 25, 1991 13:12:59'
});

console.log(new Date()); // December 25, 1991 13:12:59

答案 1 :(得分:9)

我测试了你的代码:

// create a date object for this Friday:
var d = new Date(2012, 0, 20);
//override Date constructor so all newly constructed dates return this Friday
Date = function(){return d;};

var now = new Date()
console.log(now);

now = new Date()
console.log(now);

now = new Date()
console.log(now);

now = new Date()
console.log(now);

结果????为何如此不同?

Date {Fri Jan 20 2012 00:00:00 GMT+0700 (SE Asia Standard Time)}
Date {Fri Jan 20 2012 00:00:00 GMT+0700 (SE Asia Standard Time)}
Date {Fri Jan 20 2012 00:00:00 GMT+0700 (SE Asia Standard Time)}
Date {Fri Jan 20 2012 00:00:00 GMT+0700 (SE Asia Standard Time)}

编辑:

我看到,每当您与日期选择器交互时,行为就会有所不同。尝试另一个测试,更改now就像与日期选择器交互一样:

// create a date object for this Friday:
var d = new Date(2012, 0, 20);
//override Date constructor so all newly constructed dates return this Friday
Date = function(){return d;};

var now = new Date();
var another = new Date();
console.log(now);

another.setDate(13);

now = new Date()
console.log(now);

结果是:

Date {Fri Jan 20 2012 00:00:00 GMT+0700 (SE Asia Standard Time)}
Date {Fri Jan 13 2012 00:00:00 GMT+0700 (SE Asia Standard Time)}

那么,出了什么问题? 您已经通过

覆盖核心日期功能
Date = function(){return d;}; // after construction, all date will be d (2012-01-20)
var now = new Date(); // you instantiate a date, but actually now variable is d (2012-01-20)
var another = new Date(); // you instantiate a date, but another is still d (2012-01-20)
another.setDate(13); // change another date to 13 is to change now to 13 (because now and another is still one d)

now = new Date() // still d
console.log(now); // print out now (2012-01-13)

因此,您通过一个函数覆盖核心Date函数,该函数导致所有日期使用相同(仅一个)实例,即d(2012-01-20)。更改任何影响他人的日期。

答案 2 :(得分:1)

这对我有用。

I.E如何返回1分钟后的处理时间

Date = class extends Date{
     constructor(options) {
       if (options) {
         super(options);
       } else {
         super(Date.now() - 1000 * 60);
       }
     }
   };

答案 3 :(得分:0)

Alex Stanovsky的答案几乎对我有用,但是此修改使构造函数像以前一样在给定参数的情况下工作。

    Date = class extends Date {
      constructor(...options) {
        if (options.length) {
          super(...options);
        } else {
          super(2019, 2, 11, 19, 19);
        }
      }
    };

答案 4 :(得分:0)

我使用以下内容强制执行UTC日期

var _f = function(item) { 
   Date.prototype["get" + item] = Date.prototype["getUTC" + item];  
   Date.prototype["set" + item] = Date.prototype["setUTC" + item];  
}
var _d = ['Milliseconds', 'Seconds', 'Minutes', 'Hours', 'Date', 'Month', 'FullYear', 'Year', 'Day'];
_d.forEach(_f);

Date = class extends Date {
   constructor(...options) {
      if (options.length == 1 && options[0].constructor == Date) {
         super(options[0]);
      } else if (options.length > 0) {
         super(Date.UTC(...options));
      } else {
         super(Date.UTC());
      }
   }
};