В базе данных Oracle есть две настройки часового пояса: база данных и сеанс. Они могут быть разными. Вы можете найти, что это со следующим:
select dbtimezone db, sessiontimezone sess from dual;
DB SESS
------------------------------ ------------------------------
+00:00 Europe/London
alter session set time_zone = 'Australia/Perth';
select dbtimezone db, sessiontimezone sess from dual;
DB SESS
------------------------------ ------------------------------
+00:00 Australia/Perth
Вы можете преобразовать временную метку из одного часового пояса в другой с помощью предложения at time zone
. Например:
alter session set time_zone = 'Europe/London';
select systimestamp server,
systimestamp at time zone sessiontimezone sess,
systimestamp at time zone 'Asia/Calcutta' india,
current_timestamp curr_ts
from dual;
SERVER SESS INDIA CURR_TS
----------------------------------- ---------------------------------------- ---------------------------------------- ----------------------------------------
28-AUG-18 08.46.59.104889 -07:00 28-AUG-18 16.46.59.104889 EUROPE/LONDON 28-AUG-18 21.16.59.104889 ASIA/CALCUTTA 28-AUG-18 16.46.59.104899 EUROPE/LONDON
Примечание: systimestamp возвращает дату, время и часовой пояс сервера. Это может отличаться от DBTIMEZONE
! Current_timestamp - часовой пояс сеанса.
Как именно работает это преобразование, зависит от того, как вы сохранили свои значения.
Существует три типа меток времени:
- отметка времени
- отметка времени с часовым поясом
- отметка времени с местным часовым поясом
Обычные старые временные метки не содержат информации о часовом поясе. Так что вам нужно знать, в каком TZ ваше приложение хранит его! Добавление предложения at time zone
возвращает то же время с добавлением часового пояса.
Временная метка с сохранением часового пояса сохраняет часовой пояс как есть. Использование at time zone
возвращает дату, конвертированную в указанный часовой пояс.
Местные часовые пояса нормализуют данные в соответствии с часовым поясом базы данных. Когда вы запрашиваете их, база данных преобразует их в часовой пояс сеанса. Использование at time zone
возвращает дату, преобразованную в указанный часовой пояс.
create table t (
ts timestamp,
ts_tz timestamp with time zone,
ts_ltz timestamp with local time zone
);
insert into t values (
timestamp '2018-01-01 00:00:00', timestamp '2018-01-01 00:00:00 UTC', timestamp '2018-01-01 00:00:00 UTC'
);
insert into t values (
timestamp '2018-01-01 00:00:00', timestamp '2018-01-01 00:00:00 America/Denver', timestamp '2018-01-01 00:00:00 America/Denver'
);
select * from t;
TS TS_TZ TS_LTZ
---------------------------------------- ---------------------------------------- ----------------------------------------
01-JAN-18 00.00.00.000000 01-JAN-18 00.00.00.000000 UTC 01-JAN-18 00.00.00.000000
01-JAN-18 00.00.00.000000 01-JAN-18 00.00.00.000000 AMERICA/DENVER 01-JAN-18 07.00.00.000000
alter session set time_zone = 'Asia/Calcutta';
select * from t;
TS TS_TZ TS_LTZ
---------------------------------------- ---------------------------------------- ----------------------------------------
01-JAN-18 00.00.00.000000 01-JAN-18 00.00.00.000000 UTC 01-JAN-18 05.30.00.000000
01-JAN-18 00.00.00.000000 01-JAN-18 00.00.00.000000 AMERICA/DENVER 01-JAN-18 12.30.00.000000
select ts at time zone sessiontimezone ts,
ts_tz at time zone sessiontimezone ts_tz,
ts_ltz at time zone sessiontimezone ts_ltz
from t;
TS TS_TZ TS_LTZ
---------------------------------------- ---------------------------------------- ----------------------------------------
01-JAN-18 00.00.00.000000 ASIA/CALCUTTA 01-JAN-18 05.30.00.000000 ASIA/CALCUTTA 01-JAN-18 05.30.00.000000 ASIA/CALCUTTA
01-JAN-18 00.00.00.000000 ASIA/CALCUTTA 01-JAN-18 12.30.00.000000 ASIA/CALCUTTA 01-JAN-18 12.30.00.000000 ASIA/CALCUTTA
Если вы храните значения в date
, то применяются те же правила, что и для простой отметки времени.