Javascript 如何在javascript中伪造时间?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7931069/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to fake time in javascript?
提问by Leo Zhang
I would like to mock the Date constructor so that whenever I call new Date(), it always return specific time.
我想模拟 Date 构造函数,以便每当我调用 new Date() 时,它总是返回特定时间。
I found Sinon.js provide useFakeTimers to mock time. But the following code doesn't work for me.
我发现 Sinon.js 提供 useFakeTimers 来模拟时间。但以下代码对我不起作用。
sinon.useFakeTimers(new Date(2011,9,1));
//expect : 'Sat Oct 01 2011 00:00:00' ,
//result : 'Thu Oct 27 2011 10:59:44‘
var d = new Date();
回答by tothemario
sinon.useFakeTimers
accepts a timestamp (integer) as parameter, not a Date object.
sinon.useFakeTimers
接受时间戳(整数)作为参数,而不是 Date 对象。
Try with
试试
clock = sinon.useFakeTimers(new Date(2011,9,1).getTime());
new Date(); //=> return the fake Date 'Sat Oct 01 2011 00:00:00'
clock.restore();
new Date(); //=> will return the real time again (now)
If you use anything like setTimeout
, make sure you read the docs because the useFakeTimers
will disrupt the expected behavior of that code.
如果您使用类似setTimeout
,请确保您阅读文档,因为这useFakeTimers
会破坏该代码的预期行为。
回答by Mike Christensen
How about something like this?
这样的事情怎么样?
var oldDate = Date;
Date = function (fake)
{
return new oldDate('03/08/1980');
}
var x = new Date();
document.write(x);
You'd then, of course, run:
你当然会运行:
Date = oldDate;
Date = oldDate;
When you wanted to restore things to normal behavior.
当您想将事情恢复到正常行为时。
回答by Gilles Castel
回答by Bjorkegeek
This is what I needed for my project. A bit complex, but as far as I can tell it's all needed. The internal Date() is a strange beast. Also the code below uses underscorejs.
这是我的项目所需要的。有点复杂,但据我所知,这一切都需要。内部 Date() 是一个奇怪的野兽。下面的代码也使用 underscorejs。
(window || global).Date = (function (orgDate) {
var fakeDate = function (y, m, d, ho, mi, se, mil) {
var backendDate;
if (arguments.length > 3) {
backendDate = new orgDate(y, m, d, ho || 0, mi || 0, se || 0, mil || 0);
} else if (arguments.length > 1) {
backendDate = new orgDate(y, m || 0, d || 0);
} else if (arguments.length > 0) {
backendDate = new orgDate(y);
} else {
backendDate = new orgDate();
backendDate.setFullYear(2015); // <-- Your year here
backendDate.setMonth(1); // <-- Your month here
backendDate.setDate(2); // <-- Your day here
}
if (this) {
this.backendDate = backendDate;
}
return backendDate.toString();
}
_.each(("getDate getDay getFullYear getHours getMilliseconds getMinutes " +
"getMonth getSeconds getTime getTimezoneOffset getUTCDate getUTCDay " +
"getUTCFullYear getUTCHours getUTCMilliseconds getUTCMinutes " +
"getUTCMonth getUTCSeconds getYear parse setDate setFullYear setHours " +
"setMilliseconds setMinutes setMonth setSeconds setTime setUTCDate " +
"setUTCFullYear setUTCHours setUTCMilliseconds setUTCMinutes " +
"setUTCMonth setUTCSeconds setYear toDateString toGMTString " +
"toISOString toJSON toLocaleDateString toLocaleTimeString " +
"toLocaleString toString toTimeString toUTCString UTC valueOf").split(" "),
function (fnName) {
fakeDate.prototype[fnName] = function () {
return this.backendDate[fnName].apply(this.backendDate, arguments);
}
});
return fakeDate;
})(window.Date);
回答by Jan Prichystal
I ended up doing:
我最终做了:
var oldDate = Date;
Date = function (fake)
{
if( ! fake ) return new oldDate('02/26/2017');
return new oldDate(fake);
}
Date.prototype = oldDate.prototype;
回答by Anatoli Klamer
sinon.useFakeTimers is using lolex internally. So it supports object as parameter for lolex
sinon.useFakeTimers 在内部使用 lolex。所以它支持对象作为lolex的参数
sinon.useFakeTimers(new Date(2019,1,1))
is equivalent for
等价于
sinon.useFakeTimers({
now:new Date(2019,1,1)
})
My task was to use same begin date on every integration test (as date should be connected with data in files) So how i'm using it
我的任务是在每个集成测试中使用相同的开始日期(因为日期应该与文件中的数据相关联) 那么我是如何使用它的
clock = sinon.useFakeTimers({
now,
shouldAdvanceTime: true,
advanceTimeDelta: 20
});
shouldAdvanceTime
will allows lolex and sinon to not stop timers in my integration tests.
Also take a look on config.toFake
parameter. It allows to avoid mocking some functions like setTimeout
. Or just mock only Date
constructor
shouldAdvanceTime
将允许 lolex 和 sinon 在我的集成测试中不停止计时器。还要看一下config.toFake
参数。它允许避免模拟某些函数,例如setTimeout
. 或者只是模拟Date
构造函数