PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Holen Sie sich die Zeit mit Zeitzone aus der Zeit ohne Zeitzone und dem Namen der Zeitzone

WARNUNG:PostgreSQL-Neuling (siehe Kommentare zur Frage!). Ich kenne mich allerdings ein wenig mit Zeitzonen aus, also weiß ich, was Sinn ergibt fragen.

Es sieht für mich so aus, als ob dies (leider) im Grunde eine nicht unterstützte Situation ist, wenn es um AT TIME ZONE geht . Betrachten Sie die AT TIME ZONE Dokumentation gibt es eine Tabelle, in der die "Eingabe"-Werttypen nur sind:

  • Zeitstempel ohne Zeitzone
  • Zeitstempel mit Zeitzone
  • Zeit mit Zeitzone

Uns fehlt, was Sie wollen:Zeit ohne Zeitzone. Was Sie fragen, ist etwas logisch, obwohl es vom Datum abhängt ... da verschiedene Zeitzonen je nach Datum unterschiedliche Offsets haben können. Beispiel:12:00:00 Europa/London kann bedeutet 12:00:00 UTC oder 11:00:00 UTC, je nachdem, ob es Winter oder Sommer ist.

Nachdem ich auf meinem System die Systemzeitzone auf America/Regina eingestellt habe, wird die Abfrage

SELECT ('2011-11-22T12:00:00'::TIMESTAMP WITHOUT TIME ZONE) 
                               AT TIME ZONE 'America/Vancouver'

gibt mir 2011-11-22 14:00:00-06 als Ergebnis. Das ist nicht ideal , aber es gibt zumindest den momentanen Zeitpunkt an (glaube ich). Ich glaube, wenn Sie das mit einer Client-Bibliothek abgerufen haben - oder es mit einem anderen TIMESTAMP WITH TIME ZONE verglichen haben - Sie würden das richtige Ergebnis erhalten. Es ist nur die Textkonvertierung, die dann das System verwendet Zeitzone für die Ausgabe.

Wäre das gut genug für dich? Können Sie entweder Ihre SCHEDULES.time ändern als TIMESTAMP WITHOUT TIME ZONE oder (zur Abfragezeit) die Zeit aus dem Feld mit einem Datum kombinieren, um einen Zeitstempel ohne Zeitzone zu erstellen?

BEARBEITEN:Wenn Sie mit dem "aktuellen Datum" zufrieden sind, sieht es aus wie Sie Ihre Abfrage einfach ändern können in:

SELECT (current_date + SCHEDULES.time) AT TIME ZONE USERS.tz
from SCHEDULES JOIN USERS on USERS.ID=SCHEDULES.USERID

Natürlich das aktuelle System Das Datum ist möglicherweise nicht dasselbe wie das aktuelle Datum in der lokalen Zeitzone . Ich denke das wird diesen Teil reparieren...

SELECT ((current_timestamp AT TIME ZONE USERS.tz)::DATE + schedules.time)
       AT TIME ZONE USERS.tz
from SCHEDULES JOIN USERS on USERS.ID=SCHEDULES.USERID

Mit anderen Worten:

  • Nehmen Sie den aktuellen Moment
  • Ermitteln Sie das lokale Datum/die lokale Uhrzeit in der Zeitzone des Benutzers
  • Nehmen Sie das Datum davon
  • Fügen Sie die geplante Uhrzeit zu diesem Datum hinzu, um einen TIMESTAMP WITHOUT TIME ZONE zu erhalten
  • Verwenden Sie AT TIME ZONE um die Zeitzone auf dieses lokale Datum/diese lokale Uhrzeit anzuwenden

Ich bin mir sicher, dass es einen besseren Weg gibt, aber ich denke es macht Sinn.

Sie sollten sich jedoch darüber im Klaren sein, dass dies in einigen Fällen fehlschlagen kann:

  • Was soll das Ergebnis für eine Zeit von 01:30 Uhr an einem Tag sein, an dem die Uhr von 01:00 Uhr auf 02:00 Uhr springt, sodass 01:30 Uhr überhaupt nicht vorkommt?
  • Was soll das Ergebnis für eine Zeit von 01:30 Uhr an einem Tag sein, wenn die Uhr von 02:00 Uhr auf 01:00 Uhr zurückgeht, also 01:30 Uhr zweimal vorkommt?