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());
}

它工作正常,向服务器提供客户端日期似乎很麻烦。
答案 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 中的值是客户端值,则必须知道客户端时区偏移量,以便将它们调整为正确的日期