简体   繁体   English

覆盖 Javascript 日期构造函数?

[英]Overriding the Javascript Date constructor?

I am developing a browser application that is sensitive to the current date.我正在开发一个对当前日期敏感的浏览器应用程序。

Throughout my application's code, I call new Date and perform calculations based on the current time and render the view accordingly.在我的应用程序代码中,我调用new Date并根据当前时间执行计算并相应地呈现视图。

In order to test my application for different potential calendar days, I would have to constantly change my system clock to the past or future, which is an annoyance and probably not healthy for my computer.为了在不同的潜在日历日测试我的应用程序,我必须不断地将系统时钟更改为过去或未来,这很烦人,而且可能对我的计算机不健康。

So purely for testing purposes (I would never use this code in production), I decided to override the built-in Date constructor by doing this in the console:因此纯粹出于测试目的(我永远不会在生产中使用此代码),我决定通过在控制台中执行此操作来覆盖内置的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}

With this assumption in mind, I tried this and got strange results:考虑到这个假设,我尝试了这个并得到了奇怪的结果:

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)

...and so on.... ...等等....

My question is, what exactly is going on here?我的问题是,这里到底发生了什么?

If I overrode the constructor to return a static date, why does it give unrelated and constantly incrementing dates?如果我覆盖构造函数以返回静态日期,为什么它会给出不相关且不断增加的日期?

Also, is there an effective way I can override the Date constructor to return a static date in the future without having to go through all date instantiation calls in my code and modifying the output?另外,是否有一种有效的方法可以覆盖 Date 构造函数以在将来返回静态日期而不必在我的代码中执行所有日期实例化调用并修改输出?

Thanks in advance.提前致谢。

EDIT:编辑:

I tried my code in a fresh window and it worked as expected.我在一个新窗口中尝试了我的代码,它按预期工作。

It seems the culprit was the jQuery UI datepicker plugin which was calling its "refresh" method.罪魁祸首似乎是调用其“刷新”方法的 jQuery UI datepicker 插件。 When I disable its call, the date overriding works normally, but as soon as I use the datepicker, the strange behavior above occurs.当我禁用它的调用时,日期覆盖正常工作,但是一旦我使用日期选择器,就会发生上述奇怪的行为。

No idea why this popular plugin would somehow affect something global like this.不知道为什么这个流行的插件会以某种方式影响这样的全局。 If anyone has any ideas, let me know.如果有人有任何想法,请告诉我。

Sorry for not figuring out the true culprit earlier.很抱歉没有早点找出真正的罪魁祸首。

I also faced this problem and ended up writing a module for that.我也遇到了这个问题,最终为此编写了一个模块。 Perhaps it's useful for somebody:也许它对某人有用:

Github: https://github.com/schickling/timemachine 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

I tested your code:我测试了你的代码:

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

And the result ????结果呢???? Why so different?为什么如此不同?

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)}

EDIT:编辑:

I saw that whenever you interact with the Date Picker, the behavior goes different.我看到每当您与日期选择器交互时,行为都会有所不同。 Try another test, change the now is something like interact with Date Picker:尝试另一个测试,更改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);

And the result is:结果是:

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)}

So, what goes wrong?那么,出了什么问题? You already overridden core Date function by您已经通过以下方式覆盖了核心 Date 函数

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)

So, you overrides core Date function by a function that causes all date use the same (just one) instance, which is d (2012-01-20).因此,您通过一个函数覆盖核心 Date 函数,该函数导致所有日期使用相同(仅一个)实例,即 d (2012-01-20)。 Change any dates affect others.更改任何日期会影响其他人。

This is working for me.这对我有用。

IE how to return process time 1 minute back IE 如何将处理时间返回 1 分钟

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

Give this a shot.试一试。

var d = new Date(2012, 0, 20);
// undefine date so that it will only return what your function returns
Date = undefined;   
Date = function(){return d;}

Modifying the prototype to point to your object should do the trick.修改原型以指向您的对象应该可以解决问题。

I believe the strange behavior you were experiencing earlier was that privately Date holds some notion of time, and since the prototype points to that internal clock, you were getting random times.我相信您之前遇到的奇怪行为是 Date 私下持有一些时间概念,并且由于原型指向该内部时钟,因此您获得了随机时间。

Alex Stanovsky 's answer almost did it for me but this modification made the constructor work like before when given parameters. Alex Stanovsky的回答几乎对我有用,但是这种修改使构造函数在给定参数时像以前一样工作。

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

I used the below to enforce UTC dates我使用以下内容来强制执行 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());
      }
   }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM