Was ist die beste Möglichkeit, einem Zeitstempel mit Zeitzone ein spezifiziertes Intervall hinzuzufügen, wenn ich die Berechnung nicht in der Zeitzone des Servers durchführen möchte . Dies ist besonders wichtig bei der Umstellung auf Sommerzeit.PostgresSQL: Hinzufügen eines Intervalls zu einem Zeitstempel in einer anderen Zeitzone
z.B. betrachte den Abend, an dem wir "aufspringen". (Hier in Toronto, ich glaube, es war 2016-03-13 um 2 Uhr morgens).
Wenn ich einen Zeitstempel nehmen: 2016-03-13 00:00:00-05
und füge '1 day'
es, in Canada/Eastern, würde ich erwarten, 2016-03-14 00:00:00-04
zu bekommen - später> 1 Tag, aber eigentlich nur 23 Stunden Aber wenn ich hinzufügen, 1 Tag, um es in Saskatchewan (ein Ort, der nicht DST verwendet), würde ich wollen, dass es 24 Stunden hinzufügen, so dass ich mit 2016-03-13 01:00:00-04
enden würde.
Wenn ich Spalten/Variablen
t1 timestamp with time zone;
t2 timestamp with time zone;
step interval;
zoneid text; --represents the time zone
ich im Wesentlichen
t2 = t1 + step; --in a time zone of my choosing
Postgres Dokumentation sagen will, dass der Zeitstempel mit Zeitzone, um anzuzeigen, scheint intern in UTC-Zeit gespeichert, die um anzuzeigen, scheinen dass eine Timestamptz-Spalte keine Berechnung einer Zeitzone enthält. Der SQL-Standard gibt an, dass die Operation datetime + interval die Zeitzone des ersten Operanden beibehalten soll.
t2 = (t1 AT TIME ZONE zoneid + step) AT TIME ZONE zoneid;
nicht zu funktionieren scheint, weil der erste Guss t1 in eine Zeitzone weniger Zeitstempel verwandelt und somit nicht DST
t2 = t1 + step;
scheint nicht zu arbeiten, wie es die Übergänge rechnen können tut Betrieb in der Zeitzone meines SQL-Servers
Legen Sie die Postgres-Zeitzone vor der Operation und ändern Sie sie wieder nach?
Eine bessere Darstellung:
CREATE TABLE timestamps (t1 timestamp with time zone, timelocation text);
SET Timezone 'America/Toronto';
INSERT INTO timestamps(t1, timelocation) VALUES('2016-03-13 00:00:00 America/Toronto', 'America/Toronto');
INSERT INTO timestamps(t1, timelocation) VALUES('2016-03-13 00:00:00 America/Regina', 'America/Regina');
SELECT t1, timelocation FROM timestamps; -- shows times formatted in Toronto time. OK
"2016-03-13 00:00:00-05";"America/Toronto"
"2016-03-13 01:00:00-05";"America/Regina"
SELECT t1 + '1 day', timelocation FROM timestamps; -- Toronto timestamp has advanced by 23 hours. OK. Regina time stamp has also advanced by 23 hours. NOT OK.
"2016-03-14 00:00:00-04";"America/Toronto"
"2016-03-14 01:00:00-04";"America/Regina"
Wie dies umgehen?
a) Werfen Sie die Zeitmarke auf einen Zeitstempel tz in der entsprechenden Zeitzone?
SELECT t1 AT TIME ZONE timelocation + '1 day', timelocation FROM timestamps; --OK. Though my results are timestamps without time zone now.
"2016-03-14 00:00:00";"America/Toronto"
"2016-03-14 00:00:00";"America/Regina"
SELECT t1 AT TIME ZONE timelocation + '4 hours', timelocation FROM timestamps; -- NOT OK. I want the Toronto time to be 5am
"2016-03-13 04:00:00";"America/Toronto"
"2016-03-13 04:00:00";"America/Regina"
b) Änderung der Zeitzone der Postgres und fortzufahren.
Diese Lösung funktioniert nur, wenn ich die Postgres-Zeitzone vor jedem Betriebszeitintervall kontinuierlich umschalte.
Edit: Die Variablen t1 und t2 sollten als "Zeitstempel mit Zeitzone" geschrieben worden sein. Entschuldigung, ich bin neu hier und kann die Bearbeitungsschaltfläche nicht finden. – djmorris