2017-10-07 39 views
1

我试图在startDate和endDate之间使用“date”字段获取所有记录。根据日期筛选Mongodb时区问题

我查询这个数据库(从月初的得到记录,直到今天):

var startDate = new Date(2017,09,1); 
    var endDate = new Date(2017,09,7); 

//console.log(startDate) = Sun Oct 01 2017 00:00:00 GMT-0300 (BRT) 
//console.log(endDate) = Sat Oct 07 2017 00:00:00 GMT-0300 (BRT) 

    Sale.find({date:{"$gte":startDate,"$lt":endDate}},function(err, sales){ 

    } 

记录与10/02和10/07并恢复之间的日期,但记录了日期10/01没有被退回。下面是对这些缺失的记录日期字段:

"date": { 
     "$date": "2017-10-01T23:00:00.000Z" 
    } 

我小时设置为23,看它是否会有所作为(时区等),但事实并非如此。

如果我将startDate设置为9月30日23小时,则无。小时22,21,没什么。 当startDate变为9月30日20小时宾果时,返回记录。

这可能是一个时区问题,但我无法确定在哪里以及如何。

+0

在JS,'新的Date(2017,09,1) ;'return'Wed Nov 01 2017 00:00:00 GMT-0400(EDT)'因为0是1月份。但是,这并不能解释你所看到的行为。 –

+0

将数据写入MongoDB的时区是什么时区? UTC还是本地? –

+0

本地,但是应该是新的Date()对象吗?我用日期的console.log更新了问题。 –

回答

2

This 2017-10-01T23:00:00.000Z is GMT time。 这个new Date(2017,10,01);是你当地的时间,只要你不坐在格林威治子午线上,就不等于上述时间。

JS存储日期格林威治标准时间秒以来的一些基准日期。

所以在第一种情况下,秒数是X,第二种情况下是X + Date.getTimezoneOffset()

您可以使用此功能:

function ZDate(year,month,day) { 
    return new Date(year + "-" + month + "-" + day); 
} 

或者为RobG建议:

function ZDate(year,month,day) { 
    return Date.UTC(year, month-1, day); 
} 

这里:

var startDate = ZDate(2017,09,1); 
var endDate = ZDate(2017,09,7); ` 
+0

我已经更新了我的答案。但是,您需要首先决定对您来说2017,09,1是什么意思。您当地TZ的日期,然后您的代码是正确的,或者2017,09,1是GMT,然后使用上面的ZDate。 –

+2

请注意,在ISO 8601中,仅限日期的表单不允许时区,因此附加的“Z”会被忽略或视为无效日期。由于ECMA-262版本6,仅限于日期的格式*应被视为UTC(与ISO 8601相反),因此'新日期('2017-10-01')'为UTC。如果你想明确地把它当作UTC,那么'new Date(Date.UTC(y,m-1,d))'是一个更好的方法(避免内置解析器的变幻莫测)。 – RobG