根据客户日期查询mongodb日期

时间:2017-05-10 16:47:01

标签: javascript node.js mongodb date

Mongodb以UTC格式存储日期对象。我需要根据"今天"查询客户输入的任务。今天不同于用户的观点,他们可以在东部时区或太平洋地区。这是我遇到的问题:

记录输入为" 2017-05-10 15:15:11.283Z"。当我晚上稍后查询服务器时,服务器日期将已经是2017-05-11,但是从客户的角度来看,它仍然是2015-05-10。

我需要找到客户输入的所有任务"今天"。

我试过了:



let start = new Date();
start.setHours(0,0,0,0);

let end = new Date();
end.setHours(23,59,59,999);




但是虽然这在白天(同一天)有效,但是当客户在晚上查询但在午夜之前查询时,它不会显示记录。

根据以下评论和我自己的头脑风暴,我现在将客户日期传递给服务器,并转换为UTC,如下所示:



let clientDate =  req.params.month +'/'+ req.params.date +'/'+ req.params.year;  //'5/10/2017'
console.log('clientDate ' + clientDate);

let start = new Date(clientDate);
start.setHours(0,0,0,0);
start = convertDateToUTC(start);

let end = new Date(clientDate); 
end.setDate(end.getDate() + 1);   //need this, otherwise queries next day
end.setHours(0,0,0,0);
end = convertDateToUTC(end);

console.log('start ' + start +' end ' + end);   
            
return Taks.find({goalId: {$in: goalIds}, createdAt: {$gte: start, $lt: end}}).lean() //only today


//using function found on stack overflow
function convertDateToUTC(date) { 
    return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds()); 
}




它工作正常,向服务器提供客户端日期似乎很麻烦。

1 个答案:

答案 0 :(得分:0)

如果我理解正确,日期将存储在数据库字符串中,时区偏移量为+00:00。你想获得"今天"的开始和结束的Date对象。在客户的时区(无论可能是什么)。

以下假设(可能不正确) req.params 中的值为UTC,但在进行处理的主机系统上被视为本地值:

let clientDate =  req.params.month +'/'+ req.params.date +'/'+ req.params.year;  //'5/10/2017'
console.log('clientDate ' + clientDate);

let start = new Date(clientDate);

这就是为什么你的日期超出了时区偏移量,你必须将它们移回。

您不应该创建一个字符串,然后将其留给Date构造函数来解析它。将值直接赋给Date构造函数。

接下来,您似乎想要为UTC日期所在的当地日期的开始和结束创建日期,因此以下内容应该这样做:



var req = {
  params: {
    year: '2017',
    month: '5',
    date: '10'
  }
};

// No parsing, treat date values as UTC
var clientDate = new Date(Date.UTC(req.params.year, req.params.month - 1, req.params.date));

// Copy date
var start = new Date(clientDate);

// Set to local start of day
start.setHours(0,0,0,0);

// Copy start to end and add 24 hours
var end = new Date(start);

// Adjusting UTC hours avoids daylight saving issues
// Could also just add 1 to the date
end.setUTCHours(end.getUTCHours() + 24)

console.log('Client date: ' + clientDate.toISOString() +
  '\nstart date : ' + start.toString() +
  '\nend date   : ' + end.toString());




对我来说,在格林威治以东,5月10日UTC的开始于5月10日在我当地的时区,所以我看到5月10日的开始和结束日期。对于格林威治以西的用户,5月10日将于5月9日开始,因此他们将看到5月9日的开始和结束日期。

我希望这是有道理的(并且是你所追求的)。

另一方面,如果 req.params 中的值是客户端值,则必须知道客户端时区偏移量,以便将它们调整为正确的日期