2017-05-10 2 views
0

Mongodb는 날짜 오브젝트를 UTC로 저장합니다. 나는 "오늘"을 기반으로 클라이언트가 입력 한 작업을 쿼리해야합니다. 오늘은 동양 표준 시간대 또는 태평양에있을 수있는 사용자 관점에서 다릅니다. 다음은 내가 만난 문제입니다 :클라이언트 날짜를 기반으로 mongodb 날짜 쿼리

레코드는 "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

당신은 클라이언트 timezone을 전달해야하며 쿼리를 고려해야합니다. –

+1

UTC로 변환하고 있습니까 ?? – thedarkcoder

답변

0

올바르게 이해하면 날짜는 데이터베이스 시간대 오프셋 +00 : 00과 함께 데이터베이스 문자열에 저장됩니다. 클라이언트의 시간대에서 "오늘"의 시작과 끝에 대한 Date 객체를 가져오고 싶습니다.

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

let start = new Date(clientDate); 

날짜는 이유 :

다음은 req.params의 값은 UTC 있지만, 처리를하고있는 호스트 시스템에 로컬로 취급되고 있음 (아마도 잘못) 가정 시간대 오프셋에 의해 꺼내고 그들을 다시 이동해야합니다.

문자열을 생성 한 다음 구문 분석을 위해 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 경우 해야는 정확한 날짜로 조정하기 위해 오프셋 클라이언트의 시간대를 알고있다.

관련 문제