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

PostgreSQL date() mit Zeitzone

Was Sie im Grunde wollen, ist:

$ select starts_at AT TIME ZONE 'UTC' AT TIME ZONE 'US/Pacific' from schedules where id = 40

Ich habe die Lösung aus diesem Artikel unten, die direkt GOLD ist !!! Es erklärt dieses nicht triviale Problem sehr klar, lesen Sie es, wenn Sie die Verwaltung von pstgrsql TZ besser verstehen möchten.

Ausdruck von PostgreSQL-Zeitstempeln ohne Zonen in Ortszeit

Hier ist, was los ist. Zunächst sollten Sie wissen, dass die PST-Zeitzone 8 Stunden hinter der UTC-Zeitzone liegt, also entspricht beispielsweise der 1. Januar 2014, 16:30 Uhr PST (Mi, 1. Januar 2014, 16:00:30 -0800) dem 2. Januar 2014, 00:30 Uhr AM UTC (Do, 02. Januar 2014 00:00:30 +0000). Jeder Zeitpunkt nach 16:00 Uhr in PST wechselt zum nächsten Tag, interpretiert als UTC.

Außerdem hat postresql, wie Erwin Brandstetter oben erwähnte, zwei Arten von Zeitstempel-Datentypen, einen mit Zeitzone und einen ohne. Wenn Ihre Zeitstempel eine Zeitzone enthalten, dann einen einfachen:

$ select starts_at AT TIME ZONE 'US/Pacific' from schedules where id = 40

wird funktionieren. Wenn Ihr Zeitstempel jedoch zeitzonenlos ist, funktioniert das Ausführen des obigen Befehls nicht, und Sie müssen Ihren zeitzonenlosen Zeitstempel ZUERST in einen Zeitstempel mit einer Zeitzone konvertieren, nämlich eine UTC-Zeitzone, und ERST DANN in Ihre gewünschte 'PST' oder 'US/ Pacific' (die bis auf einige Probleme mit der Sommerzeit gleich sind. Ich denke, Sie sollten mit beiden zufrieden sein).

Lassen Sie mich anhand eines Beispiels demonstrieren, in dem ich einen zeitzonenlosen Zeitstempel erstelle. Nehmen wir der Einfachheit halber an, dass unsere lokale Zeitzone tatsächlich 'PST' ist (wenn dies nicht der Fall wäre, wird es etwas komplizierter, was für den Zweck dieser Erklärung unnötig ist).

Angenommen, ich habe:

$ select timestamp '2014-01-2 00:30:00' AS a, timestamp '2014-01-2 00:30:00' AT TIME ZONE 'UTC' AS b,  timestamp '2014-01-2 00:30:00' AT TIME ZONE 'UTC' AT TIME ZONE 'PST' AS c, timestamp '2014-01-2 00:30:00' AT TIME ZONE 'PST' AS d

Dies ergibt:

"a"=>"2014-01-02 00:30:00"   (This is the timezoneless timestamp)
"b"=>"2014-01-02 00:30:00+00" (This is the UTC TZ timestamp, note that up to a timezone, it is equivalent to the timezoneless one)
"c"=>"2014-01-01 16:30:00" (This is the correct 'PST' TZ conversion of the UTC timezone, if you read the documentation postgresql will not print the actual TZ for this conversion)
"d"=>"2014-01-02 08:30:00+00"

Der letzte Zeitstempel ist der Grund für all die Verwirrung bezüglich der Konvertierung des zeitzonenlosen Zeitstempels von UTC in „PST“ in Postgresql. Wenn wir schreiben:

timestamp '2014-01-2 00:30:00' AT TIME ZONE 'PST' AS d

Wir nehmen einen zeitzonenlosen Zeitstempel und versuchen, ihn in „PST TZ“ zu konvertieren (wir gehen indirekt davon aus, dass postgresql verstehen wird, dass wir möchten, dass der Zeitstempel von UTC TZ konvertiert wird, aber postresql hat eigene Pläne!). In der Praxis nimmt postgresql den zeitzonenlosen Zeitstempel ('2014-01-2 00:30:00) und behandelt ihn so, als wäre er BEREITS ein 'PST' TZ-Zeitstempel (d. h.:2014-01-2 00:30 :00 -0800) und konvertiert das in die UTC-Zeitzone!!! Es verschiebt es also tatsächlich 8 Stunden nach vorne statt zurück! Somit erhalten wir (2014-01-02 08:30:00+00).

Wie auch immer, dieses letzte (nicht intuitive) Verhalten ist die Ursache aller Verwirrung. Lesen Sie den Artikel, wenn Sie eine gründlichere Erklärung wünschen. Ich habe tatsächlich Ergebnisse erhalten, die sich etwas von denen in diesem letzten Teil unterscheiden, aber die allgemeine Idee ist dieselbe.