Каков наилучший способ добавить указанный интервал к временной отметке с часовым поясом, если я не хочу выполнять вычисления в часовом поясе сервера , Это особенно важно для перехода на летнее время.PostgresSQL: добавление интервала к отметке времени в другом часовом поясе
например. рассмотрим вечер, когда мы «поднимемся вперед». (Здесь, в Торонто, я думаю, что это был 2016-03-13 в 2 часа ночи).
Если взять штамп времени: 2016-03-13 00:00:00-05
и добавить '1 day'
к нему, в Канаде/Восточной, я ожидаю получить 2016-03-14 00:00:00-04
-> 1 день позже, но на самом деле только 23 часа Но если добавить 1 день к нему в Saskatchewan (место, которое не использует DST), я бы хотел, чтобы он добавил 24 часа, так что я бы получил 2016-03-13 01:00:00-04
.
Если у меня есть столбцы/переменные
t1 timestamp with time zone;
t2 timestamp with time zone;
step interval;
zoneid text; --represents the time zone
я принципиально хочу сказать
t2 = t1 + step; --in a time zone of my choosing
Postgres документации, кажется, указывает, что метки времени с часовым поясом внутренне хранятся во времени UTC, который, кажется, указывают на что в столбце timestamptz нет расчёта часового пояса в нем. Стандарт SQL указывает, что Операция datetime + interval должна поддерживать часовой пояс первого операнда.
t2 = (t1 AT TIME ZONE zoneid + step) AT TIME ZONE zoneid;
, кажется, не работает, потому что первая литая превращает t1 в часовой пояс менее метки времени и, таким образом, не может считаться DST переходы
t2 = t1 + step;
, кажется, не работает, как это делает операции в часовом поясе моего SQL-сервера
установить временную зону postgres перед операцией и изменить ее после?
Лучшая иллюстрация:
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"
Как это обойти?
a) Настроить timestamptz на временную метку tz в соответствующем часовом поясе?
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) Изменить часовой пояс postgres и продолжить.
SET TIMEZONE = 'America/Regina';
SELECT t1 + '1 day', timelocation FROM timestamps; -- Now the Regina time stamp is correct, but toronto time stamp is incorrect (should be 22:00-06)
"2016-03-13 23:00:00-06";"America/Toronto"
"2016-03-14 00:00:00-06";"America/Regina"
SET TIMEZONE = 'America/Toronto';
SELECT t1 + '1 day', timelocation FROM timestamps; -- toronto is correct, regina is not, as before
"2016-03-14 00:00:00-04";"America/Toronto"
"2016-03-14 01:00:00-04";"America/Regina"
Это решение будет работать только в том случае, если я постоянно переключаю часовой пояс postgres перед каждым операционным интервалом.
Редактирование: переменные t1 и t2 должны быть записаны как «метка времени с часовым поясом». Извините, я новичок здесь и не могу найти кнопку редактирования. – djmorris