您好,想请问一下,最近在写个功能為使用者每次新增一笔资料后,还要设一个三天后过期的资料,最后再写个 setInterval 每一分钟检查一次,如果过期就标记并作其他后续处理。但不知為何,用 mongoose 设好的 schema 的日期有机会会产生跳掉的情形,而且是日期提前了,像今天 create_at 是 10 号,但 expire_date 却跑到 9 号去,造成资料一新增马上就过期,有时则是 create_at 提前了,请问这是怎么一回事?谢谢。
更正,create_at 的资料没问题,是 expire_date 算完后时间反而提前了,抱歉误导了。
node 版本是 0.8.23 mongoose: 3.8.2 mongodb: 2.0.4
//model
var Data = new Schema({
create_at: { type: Date, default: Date.now },
expire_date: { type: Date, default: (new Date().setDate(new Date().getDate() + 3)) },
expired: false
});
mongoose.model('Data', DataSchema);
// check out date
setInterval(function() {
Data.find(function(err, data) {
if(!err) {
var length = data.length;
for(var i =0; i < length; i++) {
if(!data[i].expired && new Date() > data[i].expire_date) {
data[i].expired = true;
data[i].save();
}
}
}
});
}, 60000);
@nighca 试了下,你说得对。我是c语言的思维:)javascript偶尔一用。 Date.now,不用加括号么?now是个函数吧。还有Date.now()返回的也是毫秒数,并非是Date对象。
你说的10号变9号逻辑上讲应该不会,10号变9号只是你随便举的例子?实际出错的日期没有什么规律么。
另外,不如把两个date先用var声明一下: var create_at = new Date(); var expire_date = new Date(); expire_date.setDate(create_at.getDate() + 3); 这样可以在声明Data之前加个打印调试一下。
@xuduo35 不是随便举,是今天真实发生的,时光倒流其实现在也才出现两次,但也不该出现就是,通常是倒回一到二天。
"expire_date": ISODate("2014-02-09T11:15:14.301Z"),
"create_at": ISODate("2014-02-10T08:49:40.565Z")
Date.now 跟 new Date() 是一样的,只是后者可以用 getDate、setDate 那些函式
@Knovour 从逻辑上讲我看不出什么问题了,也许是其他地方改了,你这里的代码毕竟只是一个片段。我估计未必是这段代码出错。 可以在新增记录成功的callback里直接比较create_at和expire_date,如果记录建好就出错,那么记个log。确定是这里出错或者排除这里出错以后再看。
总觉得你这句有问题 expire_date: { type: Date, default: (new Date().setDate(new Date().getDate() + 3)) }, 如果这个Schema需要的是一个Date的对象,那么default后面返回值是setDate的返回值。javascript里面setDate返回的只是调整过的一个毫秒数。