2017-01-12 4 views
1

Ich verwende pg-promise lib, um mit Postgres DB zu arbeiten. Ich verstehe nicht, warum mitPG Promise gibt "Zeitstempel mit Zeitzone" nicht korrekt zurück

SELECT date FROM ro WHERE id = 13; 

kehrt

date   
------------------------ 
2017-01-19 00:00:00+02 
(1 row) 

und dieser pgp Anruf direkt DB Abfrage:

var sql = 'SELECT date from ro WHERE id = 1366'; 
    Dbh.odb.any(sql) 
     .then(ro => { 
     console.log(ro); 
     res.ok(ro) 
     }) 

kehrt

{ 
    "date": "2017-01-18T22:00:00.000Z" 
} 

Was ich erwarte, ist

{ 
    "date": "2017-01-19T00:00:00.000Z" 
} 
+0

Die Bibliothek konvertiert möglicherweise in lokale Zeit und die Datenbank speichert sie in der lokalen Serverzeit. – ppovoski

+0

Stellen Sie sicher, dass Sie die neueste Version der Bibliothek verwenden, da die Zeit, in der die Zeit konvertiert wird, vor nicht allzu langer Zeit aktualisiert wurde. –

+0

Sie fragen übrigens nach verschiedenen Record-IDs: '13' vs' 1366'. Außerdem erhalten Sie die gleiche Zeit, aber für verschiedene Zeitzonen - 'T00' vs' T22'. –

Antwort

2

Verwenden Sie psql auf demselben Computer, auf dem Sie pg-promise ausführen?

Aus der Dokumentation auf timestamp with timezone

Für Zeitstempel mit Zeitzone ist der intern gespeicherte Wert immer in UTC (Universal Coordinated Time, traditionell bekannt als Greenwich Mean Time, GMT). Ein Eingabewert, für den eine explizite Zeitzone angegeben wurde, wird mit dem entsprechenden Offset für diese Zeitzone in UTC konvertiert. Wenn in der Eingabezeichenfolge keine Zeitzone angegeben ist, wird davon ausgegangen, dass sie sich in der Zeitzone TimeZone parameter befindet und mithilfe des Offsets für die Zeitzonenzone in UTC konvertiert wird.

Wenn ein Zeitstempel mit Zeitzonenwert ausgegeben wird, wird er immer von UTC in die aktuelle Zeitzonenzone konvertiert und als lokale Zeit in dieser Zone angezeigt. Um die Zeit in einer anderen Zeitzone zu sehen, ändern Sie entweder die Zeitzone oder verwenden Sie das AT TIME ZONE Konstrukt (siehe Abschnitt 9.9.3).

So Zeitzonen in UTC gespeichert und abgerufen basierend auf dem TimeZone Parameter, von der docs (leicht gereinigt)

Der TimeZone Konfigurationsparameter eingestellt werden kann,

  1. in die Datei postgresql.conf
  2. In einer der anderen Standard-Möglichkeiten beschrieben in Chapter 19.
  3. Der SQL-Befehl SET TIME ZONE legt die Zeitzone für die Sitzung fest. Dies ist eine alternative Schreibweise von SET TIMEZONE TO mit einer SQL-Spezifikation kompatiblen Syntax.
  4. Die PGTZ-Umgebungsvariable wird von libpq-Clients verwendet, um bei der Verbindung den Befehl SET TIME ZONE an den Server zu senden.

So konnte man immer,

var sql = `SELECT date AT TIME ZONE '+02' from ro WHERE id = 1366`; 
    Dbh.odb.any(sql) 
     .then(ro => { 
     console.log(ro); 
     res.ok(ro) 
     }) 

Oder stellen Sie die Zeitzone für den Client, Sitzung oder Server.

Sie können die möglichen Werte für timezone hier finden

SELECT * FROM pg_timezone_names(); 
2

Ihr psql Ausgabe zeigt, dass der Zeitstempel Sie haben um Mitternacht ist aber auf UTC + 2 Zeitzone (2017.01.19 00: 00: 00+) das ist zwei Stunden vor UTC.

Das heißt, wenn die Zeit 00:00:00 Uhr UTC + 2 ist, ist es nur 22:00:00 Uhr des Vortages UTC - und das bekommen Sie: 2017-01- 18T22: 00: 00.000 Z.

Wenn Sie ein JavaScript-Datum von diesem UTC-Datum erstellen, erhalten Sie Mitternacht, wenn Sie UTC + 2 verwenden. Dies ist, was ich in Chrome-Konsole auf UTC sehen + 2:

new Date('2017-01-18T22:00:00.000Z'); 
Thu Jan 19 2017 00:00:00 GMT+0200 (EET) 

Und wenn Sie wirklich den Zeitstempel als Mitternacht UTC gespeichert haben möchten, sollten Sie die Zeitzone festlegen, wenn Sie das Datum einfügen. Beachten Sie jedoch, dass es dann nicht Mitternacht an UTC + 2 ist:

new Date('2017-01-19T00:00:00.000Z'); 
Thu Jan 19 2017 02:00:00 GMT+0200 (EET) 
Verwandte Themen