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.useFakeTimersaccepts 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 useFakeTimerswill 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
});
shouldAdvanceTimewill allows lolex and sinon to not stop timers in my integration tests.
Also take a look on config.toFakeparameter. It allows to avoid mocking some functions like setTimeout. Or just mock only Dateconstructor
shouldAdvanceTime将允许 lolex 和 sinon 在我的集成测试中不停止计时器。还要看一下config.toFake参数。它允许避免模拟某些函数,例如setTimeout. 或者只是模拟Date构造函数

