Да, PostgreSQL хранит все метки времени как UTC внутри.Для timestamp with time zone
смещение часового пояса применяется только для настройки времени на UTC, но не сохраняется явно.
Я бы не стал хранить строку часового пояса или даже меньше часового поясасокращение (те, которые не являются точными).Позже это может потребовать дорогостоящих вычислений, потому что вы должны учитывать летнее время и другие странности международного режима времени.
Вы можете сохранить смещение часового пояса как интервал (занимает 12 байт ) или числовое количество секунд (принимает 4 байта как целое число), как я продемонстрировал в этом связанном ответе .
Или, как вы уже предлагали: сохраните локальныйотметка времени в дополнение к отметке времени UTC (занимает 8 байт ).Это облегчит ваши задачи.Рассмотрим следующую демонстрацию: *
-- DROP TABLE tbl;
CREATE TEMP TABLE tbl (id int, ts_tz timestamp with time zone, ts timestamp);
INSERT INTO tbl VALUES
(1,'2012-1-1 00:00+01','2012-1-1 00:00+01')
,(2,'2012-1-1 00:00+02','2012-1-1 00:00+02')
,(3,'2012-1-1 00:01+03','2012-1-1 00:01+03')
,(4,'2012-1-1 00:02+04','2012-1-1 00:02+04');
Запрос на вопрос 1:
SELECT *
FROM tbl
WHERE ts = '2012-1-1 00:00'::timestamp;
id | ts_tz | ts
----+------------------------+---------------------
1 | 2012-01-01 00:00:00+01 | 2012-01-01 00:00:00
2 | 2011-12-31 23:00:00+01 | 2012-01-01 00:00:00
Запрос на вопрос 2:
SELECT *
FROM tbl
ORDER BY ts_tz;
id | ts_tz | ts
----+------------------------+---------------------
4 | 2011-12-31 21:02:00+01 | 2012-01-01 00:02:00
3 | 2011-12-31 22:01:00+01 | 2012-01-01 00:01:00
2 | 2011-12-31 23:00:00+01 | 2012-01-01 00:00:00
1 | 2012-01-01 00:00:00+01 | 2012-01-01 00:00:00
сложная часть с этим решением может быть введено местное время.Это легко, если все данные вводятся локально.Но это необходимо учитывать, если вы вводите данные, скажем, для Нью-Йорка в Лос-Анджелесе.Для этого используйте AT TIME ZONE
конструкцию :
SELECT ('2012-1-1 00:00+00' AT TIME ZONE 'America/New_York')::timestamp
, ('2012-1-1 00:00+00' AT TIME ZONE 'America/Los_Angeles')::timestamp
timezone | timezone
---------------------+---------------------
2011-12-31 19:00:00 | 2011-12-31 16:00:00
Обратите внимание, как я использую метку времени с часовым поясом в качестве входных данных.AT TIME ZONE
дает разные результаты для отметок времени с часовым поясом или без него.