Если у вас есть простая дата или метка времени без какой-либо вложенной информации часового пояса, вы можете сказать, Oracle, чтобы рассматривать его как в конкретной временной зоне с the from_tz()
function. Затем вы можете преобразовать это значение, которое теперь имеет временную метку типа с зоной зоны, а не обычную временную метку, - в другую зону с at time zone
datetime expression syntax, либо используя часовой пояс сеанса как «локальный», либо определенный часовой пояс :
alter session set nls_date_format='YYYY-MM-DD HH24:MI:SS';
alter session set nls_timestamp_format='YYYY-MM-DD HH24:MI:SS';
alter session set nls_timestamp_tz_format='YYYY-MM-DD HH24:MI:SS TZR';
alter session set time_zone = 'America/New_York';
with cte (ts) as (
select timestamp '2017-02-08 12:00:00' from dual
)
select ts,
from_tz(ts, 'UTC') as ts_utc,
from_tz(ts, 'UTC') at local as ts_local,
from_tz(ts, 'UTC') at time zone 'Europe/Athens' as ts_athens
from cte;
TS TS_UTC TS_LOCAL TS_ATHENS
------------------- ----------------------- ------------------------------------ ---------------------------------
2017-02-08 12:00:00 2017-02-08 12:00:00 UTC 2017-02-08 07:00:00 AMERICA/NEW_YORK 2017-02-08 14:00:00 EUROPE/ATHENS
Если вы начинаете с даты, то вы должны преобразовать его в метку времени перед вызовом from_tz()
:
with cte (dt) as (
select cast(timestamp '2017-02-08 12:00:00' as date) from dual
)
select dt,
from_tz(cast(dt as timestamp), 'UTC') as ts_utc,
from_tz(cast(dt as timestamp), 'UTC') at local as ts_local,
from_tz(cast(dt as timestamp), 'UTC') at time zone 'Europe/Athens' as ts_athens
from cte;
DT TS_UTC TS_LOCAL TS_ATHENS
------------------- ----------------------- ------------------------------------ ---------------------------------
2017-02-08 12:00:00 2017-02-08 12:00:00 UTC 2017-02-08 07:00:00 AMERICA/NEW_YORK 2017-02-08 14:00:00 EUROPE/ATHENS
так тип данных ваших исходных значений date_1
вопросов, как это делает номинальный часовой пояс, который он должен представлять. Если это: готовая «метка времени с часовым поясом» или «метка времени с местным часовым поясом», тогда она уже имеет встроенную информацию о часовом поясе, так что вам вообще не нужна часть from_tz()
. Если это дата, вам нужно преобразовать ее в метку времени.
Предполагая, что date_1
хранится в виде простой метки времени (возможно, подразумеваемой вашего интервала дополнение, но не по имени столбца и фильтров, используемых), и что это номинально UTC, вы могли бы сделать:
from_tz(date_1, 'UTC') at time zone 'Europe/Athens'
. .. который даст вам результат с меткой времени с часовым поясом; или вы можете использовать local
, чтобы полагаться на свой часовой пояс сеанса.Если `дата_1 хранится в виде даты вы бы добавить преобразование в отметку времени:
from_tz(cast(date_1 as timestamp), 'UTC') at time zone 'Europe/Athens'
В демке, генерируя временные метки (не даты) в КТР, включая некоторые вокруг изменений ДСТ в течение этого года:
with tbl_1(date_1) as (
select timestamp '2017-02-08 10:00:00' from dual
union all select timestamp '2017-02-08 11:00:00' from dual
union all select timestamp '2017-02-08 12:00:00' from dual
union all select timestamp '2017-03-23 12:00:00' + numtodsinterval(level, 'day')
from dual connect by level <= 4
)
select date_1,
-- cast(from_tz(date_1, 'UTC') at time zone 'Europe/Athens' as timestamp) as date_2
to_char(from_tz(date_1, 'UTC') at time zone 'Europe/Athens',
'DD.MM.YYYY HH24:MI') as date_2
from tbl_1
order by date_1;
DATE_1 DATE_2
------------------- ----------------
2017-02-08 10:00:00 08.02.2017 12:00
2017-02-08 11:00:00 08.02.2017 13:00
2017-02-08 12:00:00 08.02.2017 14:00
2017-03-24 12:00:00 24.03.2017 14:00
2017-03-25 12:00:00 25.03.2017 14:00
2017-03-26 12:00:00 26.03.2017 15:00
2017-03-27 12:00:00 27.03.2017 15:00
Вы можете видеть, что дополнительный час добавляется автоматически после смены часов 26 марта. Но результаты выходят за час для ваших данных образца февраля - так что ваши данные фактически не хранятся в формате UTC (но есть -01: 00, и вы можете изменить вызов from_tz()
, чтобы это отразить), или ваши ожидаемые результаты неправильно.
Почему знак postgresql? Вы не используете Oracle? – jarlh
Каким типом данных является столбец 'date_1', и в каком часовом поясе находятся значения, которые он содержит номинально? –
@Alex Poole Тип 'date_1' -' DATE', а часовой пояс - «Европа/Афины» – BOB