2017-10-07 4 views
1

Ich versuche, alle Datensätze mit "Datum" -Feld zwischen StartDate und EndDate zu bekommen.Mongodb Zeitzone Problem beim Filtern nach Datum

ich die DB mit diesem bin Abfrage (Aufzeichnungen von Anfang des Monats bis heute zu erhalten):

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){ 

    } 

Aufzeichnungen mit Daten zwischen 10/02 und 10/07 und zurückgegeben werden, aber Aufzeichnungen mit Datum 10/01 werden nicht zurückgegeben. Hier ist das Datumsfeld dieser fehlenden Datensätze:

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

ich die Stunden bis 23 zu sehen, ob es einen Unterschied machen würde (Zeitzone, usw.), aber es kam nicht.

Wenn ich das Startdatum auf 30 September 23 September, nichts einstellen. Stunde 22, 21, nichts. Wenn startDate 30. September, Stunde 20, Bingo wird, werden die Datensätze zurückgegeben.

Dies ist wahrscheinlich ein Zeitzonenproblem, aber ich kann nicht identifizieren, wo und wie.

+0

In JS, 'new Date (2017,09,1) ; 'returns' Wed Nov 01 2017 00:00:00 GMT-0400 (EDT) 'weil 0 Januar ist. Das erklärt jedoch nicht das Verhalten, das Sie sehen. –

+0

In welcher Zeitzone werden Ihre Daten in MongoDB geschrieben? UTC oder lokal? –

+0

Lokal, aber so sollte das neue Date() Objekt richtig sein? Ich habe die Frage mit der console.log der Daten aktualisiert. –

Antwort

2

Diese 2017-10-01T23:00:00.000Z ist GMT Zeit. Diese new Date(2017,10,01); ist Ihre Ortszeit und entspricht nicht der oben genannten, sobald Sie nicht auf Greenwich Meridian sitzen.

JS speichert Daten in GMT-Sekunden seit einem bestimmten Basisdatum.

Also im ersten Fall ist die Anzahl der Sekunden X und im zweiten Fall ist es X + Date.getTimezoneOffset().

Sie diese Funktion nutzen zu können:

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

Oder wie RobG vorgeschlagen:

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

hier:

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

Ich habe meine Antwort aktualisiert. Aber Sie müssen zuerst entscheiden, was es für Sie bedeutet 2017,09,1. Datum in Ihrem lokalen TZ, dann ist Ihr Code korrekt oder 2017,09,1 ist GMT, dann benutzen Sie ZDate oben. –

+2

Beachten Sie, dass in Form von Nur-Datum-Formularen in ISO 8601 keine Zeitzone zulässig ist, sodass ein angehängtes "Z" entweder ignoriert oder wie in einem ungültigen Datum behandelt wird. Seit ECMA-262 ed 6 sollten Datumsformulare * als UTC behandelt werden (im Gegensatz zu ISO 8601), so dass "neues Datum ('2017-10-01')" UTC ist. Wenn Sie es explizit als UTC behandeln wollen, dann ist 'neues Datum (Date.UTC (y, m-1, d)) 'ein viel besserer Weg (und vermeidet die Launen des eingebauten Parsers). – RobG