我们的数据存储在UTC + 00:00的时区。
要进行一些查询,我们必须将时间戳输入从“欧洲/巴黎”时区转换为UTC + 00:00,即欧洲/伦敦。 当我们获得此数据时,将输出时间戳转换为“欧洲/巴黎”时区。
所以我找到的解决方案是使用像cast(VALIDATIONTIME as timestamp) at time zone 'Europe/Paris'
这样的“在时区”
它适用于输入,但不适用于输出(当我们获取数据时)。
那么如何使它适用于输入和输出?
示例:
Orders table
ID VALIDATIONTIME
9986 14/03/16 09:47:29,823000000
6764 20/03/16 12:07:39,453000000
要获取行ID 9986,查询将为:
select cast(VALIDATIONTIME as timestamp) at time zone 'Europe/Paris' as validation
from orders
where VALIDATIONTIME between cast(TO_TIMESTAMP('14/03/2016 10:45:18', 'DD/MM/YYYY HH24:MI:SS') as timestamp) at time zone 'UTC'
and cast(TO_TIMESTAMP('14/03/2016 10:50:18', 'DD/MM/YYYY HH24:MI:SS') as timestamp) at time zone 'UTC';
但输出(验证)不会改变!!
答案 0 :(得分:1)
at time zone
syntax将带有时区值的时间戳从其当前区域转换为您指定的时区。当您将其应用于没有时区的普通时间戳时,当您跟随cast()
时,会先隐式转换为会话时区。
我认为你真的在寻找the from_tz()
function:
select VALIDATIONTIME at time zone 'Europe/Paris' as validation
from orders
where VALIDATIONTIME between
FROM_TZ(TO_TIMESTAMP('14/03/2016 10:45:18', 'DD/MM/YYYY HH24:MI:SS'), 'Europe/Paris')
and
FROM_TZ(TO_TIMESTAMP('14/03/2016 10:50:18', 'DD/MM/YYYY HH24:MI:SS'), 'Europe/Paris');
您可以通过独立查询查看生成的时间;这也将指定为巴黎时区的时间转换为UTC进行比较:
select
FROM_TZ(TO_TIMESTAMP('14/03/2016 10:45:18', 'DD/MM/YYYY HH24:MI:SS'), 'Europe/Paris')
as Paris,
FROM_TZ(TO_TIMESTAMP('14/03/2016 10:45:18', 'DD/MM/YYYY HH24:MI:SS'), 'Europe/Paris')
at time zone 'UTC' as London
from dual;
PARIS LONDON
------------------------------------------ ------------------------------------------
14-MAR-16 10.45.18.000000000 EUROPE/PARIS 14-MAR-16 09.45.18.000000000 UTC
(当然,伦敦在夏天不是UTC,但我们暂时忽略这个细节;我假设你真的想要UTC而不是伦敦。)
您可能需要根据其数据类型和会话时区操作validationtime
。使用一些简单的数据设置和validationtime
作为普通时间戳(没有时区信息):
create table orders (id number, validationtime timestamp);
insert into orders (id, validationtime)
values (9986, to_timestamp('14/03/16 09:47:29,823000000', 'DD/MM/RR HH24:MI:SS,FF'));
insert into orders (id, validationtime)
values (6764, to_timestamp('20/03/16 12:07:39,453000000', 'DD/MM/RR HH24:MI:SS,FF'));
如果我的会话在伦敦时间,则基本查询有效:
alter session set time_zone = 'Europe/London';
select VALIDATIONTIME at time zone 'Europe/Paris' as validation
from orders
where VALIDATIONTIME between
FROM_TZ(TO_TIMESTAMP('14/03/2016 10:45:18', 'DD/MM/YYYY HH24:MI:SS'), 'Europe/Paris')
and
FROM_TZ(TO_TIMESTAMP('14/03/2016 10:50:18', 'DD/MM/YYYY HH24:MI:SS'), 'Europe/Paris');
VALIDATION
------------------------------------------
14-MAR-16 10.47.29.823000000 EUROPE/PARIS
但是,如果我将会话时区更改为巴黎,那么它现在不会:
alter session set time_zone = 'Europe/Paris';
select VALIDATIONTIME at time zone 'Europe/Paris' as validation
from orders
where VALIDATIONTIME between
FROM_TZ(TO_TIMESTAMP('14/03/2016 10:45:18', 'DD/MM/YYYY HH24:MI:SS'), 'Europe/Paris')
and
FROM_TZ(TO_TIMESTAMP('14/03/2016 10:50:18', 'DD/MM/YYYY HH24:MI:SS'), 'Europe/Paris');
no rows selected
因此,您需要在表格中指定UTC的原始时间戳,您可以使用相同的函数执行此操作:
select FROM_TZ(VALIDATIONTIME, 'UTC') at time zone 'Europe/Paris' as validation
from orders
where FROM_TZ(VALIDATIONTIME, 'UTC') between
FROM_TZ(TO_TIMESTAMP('14/03/2016 10:45:18', 'DD/MM/YYYY HH24:MI:SS'), 'Europe/Paris')
and
FROM_TZ(TO_TIMESTAMP('14/03/2016 10:50:18', 'DD/MM/YYYY HH24:MI:SS'), 'Europe/Paris');
VALIDATION
------------------------------------------
14-MAR-16 10.47.29.823000000 EUROPE/PARIS
基本上,在比较它们之前,您需要确保所使用的所有日期都在同一区域中。另一种方法是将变量日期强制为UTC,然后强制为简单时间戳:
select FROM_TZ(VALIDATIONTIME, 'UTC') at time zone 'Europe/Paris' as validation
from orders
where VALIDATIONTIME
between
cast(FROM_TZ(TO_TIMESTAMP('14/03/2016 10:45:18', 'DD/MM/YYYY HH24:MI:SS'),
'Europe/Paris') at time zone 'UTC' as timestamp)
and
cast(FROM_TZ(TO_TIMESTAMP('14/03/2016 10:50:18', 'DD/MM/YYYY HH24:MI:SS'),
'Europe/Paris') at time zone 'UTC' as timestamp);
VALIDATION
------------------------------------------
14-MAR-16 10.47.29.823000000 EUROPE/PARIS
...看起来更复杂,但由于它不修改where
子句中的表列,它将允许仍然使用该列上的任何索引。
此处变量字符串被转换为普通时间戳,声明为在巴黎时区,转换为UTC,然后转换回普通时间戳 - 因此它的格式与(隐含)时区相同表列数据。
答案 1 :(得分:1)
Oracle安装程序:
CREATE TABLE orders (
ID INT,
VALIDATIONTIME TIMESTAMP
);
INSERT INTO orders VALUES (
9968,
FROM_TZ( TIMESTAMP '2016-03-14 09:47:29.823', 'Europe/Paris' )
AT TIME ZONE 'UTC'
);
-- Alternate syntax for inserting from TZ:
INSERT INTO orders VALUES (
6764,
TO_TIMESTAMP_TZ( '2016-03-20 20:07:39.453 Europe/Paris',
'YYYY-MM-DD HH24:MI:SS.FF TZR' )
AT TIME ZONE 'UTC'
);
甚至更简单:
INSERT INTO orders VALUES (
9968,
TIMESTAMP '2016-03-14 09:47:29.823+01:00' AT TIME ZONE 'UTC'
);
或:
INSERT INTO orders VALUES (
6764,
TIMESTAMP '2016-03-20 20:07:39.453 Europe/Paris' AT TIME ZONE 'UTC'
);
查询1 :
SELECT * FROM orders;
ID VALIDATIONTIME
---- -----------------------------
9986 2016-03-14 08:47:29.823000000
6764 2016-03-20 19:07:39.453000000
(这表示表中的UTC时间)
查询2 :
SELECT id,
CAST( VALIDATIONTIME AS TIMESTAMP WITH TIME ZONE )
AT TIME ZONE 'Europe/Paris' AS validationtime
FROM orders
ID VALIDATIONTIME
---- ------------------------------------------
9986 2016-03-14 09:47:29.823000000 EUROPE/PARIS
6764 2016-03-20 20:07:39.453000000 EUROPE/PARIS