Oracle 如何将任何时区的时间戳转换为数据库服务器时区的日期
Oracle how to convert Timestamp with any Timezone, to Date with database server Timezone
我有一个时间戳列,其中包含不同时区的数据。我需要 select 属于给定 'day' 数据库服务器时区的记录。
例如MY_TIMESTAMP
列的数据为19-MAR-19 00.37.56.030000000 EUROPE/PARIS
.
在数据库服务器位于 EUROPE/LONDON
的给定日期 19-MAR-19
(也表示为 2019078)。
有什么办法可以让我的数据库服务器在 EUROPE/LONDON
时区时忽略此记录,但如果在 EUROPE/PARIS
时区,则记录为 selected.
请注意给定的时间戳是当天的第一个小时,EUROPE/PARIS
比EUROPE/LONDON
早一个小时
不幸的是,我尝试的查询忽略了时间戳的时区。
select *
from MY_TABLE
where
to_number(to_char(CAST(MY_TIMESTAMP AS DATE), 'RRRRDDD')) between 2019078 AND 2019079
下面提到了将 TIMESTAMP 从已知时区转换为所需时区日期的方法,但我无法使用此逻辑,因为不知道源时区。
CAST((FROM_TZ(CAST(MY_TIMESTAMP AS TIMESTAMP),'EUROPE/PARIS') AT TIME ZONE 'EUROPE/LONDON') AS DATE)
'
您不需要转换table数据;这样做不仅会增加工作量,还会停止使用该列上的任何索引。
Oracle 在比较值时将遵循时区,因此将原始 table 数据与特定日期进行比较 - 并将其转换为带时区的时间戳:
select *
from MY_TABLE
where MY_TIMESTAMP >= timestamp '2019-03-19 00:00:00 Europe/London'
and MY_TIMESTAMP < timestamp '2019-03-20 00:00:00 Europe/London'
或者如果您想以今天而不是固定日期为基础:
where MY_TIMESTAMP >= from_tz(cast(trunc(sysdate) as timestamp), 'Europe/London')
and MY_TIMESTAMP < from_tz(cast(trunc(sysdate) + 1 as timestamp), 'Europe/London')
或者如果您将日期作为 YYYYDDD 值传递(用数字参数名称替换固定值):
where MY_TIMESTAMP >= from_tz(to_timestamp(to_char(2019078), 'RRRRDDD'), 'Europe/London')
and MY_TIMESTAMP < from_tz(to_timestamp(to_char(2019079), 'RRRRDDD'), 'Europe/London')
使用 CTE 中的一些样本数据进行快速演示,为简单起见分为两个区域:
with my_table (id, my_timestamp) as (
select 1, timestamp '2019-03-19 00:37:56.030000000 Europe/Paris' from dual
union all
select 2, timestamp '2019-03-19 00:37:56.030000000 Europe/London' from dual
union all
select 3, timestamp '2019-03-19 01:00:00.000000000 Europe/Paris' from dual
union all
select 4, timestamp '2019-03-20 00:37:56.030000000 Europe/Paris' from dual
union all
select 5, timestamp '2019-03-20 00:37:56.030000000 Europe/London' from dual
)
select *
from MY_TABLE
where MY_TIMESTAMP >= timestamp '2019-03-19 00:00:00 Europe/London'
and MY_TIMESTAMP < timestamp '2019-03-20 00:00:00 Europe/London'
/
ID MY_TIMESTAMP
---------- --------------------------------------------------
2 2019-03-19 00:37:56.030000000 EUROPE/LONDON
3 2019-03-19 01:00:00.000000000 EUROPE/PARIS
4 2019-03-20 00:37:56.030000000 EUROPE/PARIS
第一个示例行被排除在外,因为巴黎的 00:37 仍然是伦敦的前一天。第二行和第三行被包括在内,因为它们都在当天的凌晨 - 第三行刚刚进入。第四行被包括在内的原因与第一行被排除在外的原因相同 - 00:37 明天仍然是今天来自伦敦.第五个被排除在外,因为它是在伦敦午夜之后。
我有一个时间戳列,其中包含不同时区的数据。我需要 select 属于给定 'day' 数据库服务器时区的记录。
例如MY_TIMESTAMP
列的数据为19-MAR-19 00.37.56.030000000 EUROPE/PARIS
.
在数据库服务器位于 EUROPE/LONDON
的给定日期 19-MAR-19
(也表示为 2019078)。
有什么办法可以让我的数据库服务器在 EUROPE/LONDON
时区时忽略此记录,但如果在 EUROPE/PARIS
时区,则记录为 selected.
请注意给定的时间戳是当天的第一个小时,EUROPE/PARIS
比EUROPE/LONDON
早一个小时
不幸的是,我尝试的查询忽略了时间戳的时区。
select *
from MY_TABLE
where
to_number(to_char(CAST(MY_TIMESTAMP AS DATE), 'RRRRDDD')) between 2019078 AND 2019079
下面提到了将 TIMESTAMP 从已知时区转换为所需时区日期的方法,但我无法使用此逻辑,因为不知道源时区。
CAST((FROM_TZ(CAST(MY_TIMESTAMP AS TIMESTAMP),'EUROPE/PARIS') AT TIME ZONE 'EUROPE/LONDON') AS DATE)
'
您不需要转换table数据;这样做不仅会增加工作量,还会停止使用该列上的任何索引。
Oracle 在比较值时将遵循时区,因此将原始 table 数据与特定日期进行比较 - 并将其转换为带时区的时间戳:
select *
from MY_TABLE
where MY_TIMESTAMP >= timestamp '2019-03-19 00:00:00 Europe/London'
and MY_TIMESTAMP < timestamp '2019-03-20 00:00:00 Europe/London'
或者如果您想以今天而不是固定日期为基础:
where MY_TIMESTAMP >= from_tz(cast(trunc(sysdate) as timestamp), 'Europe/London')
and MY_TIMESTAMP < from_tz(cast(trunc(sysdate) + 1 as timestamp), 'Europe/London')
或者如果您将日期作为 YYYYDDD 值传递(用数字参数名称替换固定值):
where MY_TIMESTAMP >= from_tz(to_timestamp(to_char(2019078), 'RRRRDDD'), 'Europe/London')
and MY_TIMESTAMP < from_tz(to_timestamp(to_char(2019079), 'RRRRDDD'), 'Europe/London')
使用 CTE 中的一些样本数据进行快速演示,为简单起见分为两个区域:
with my_table (id, my_timestamp) as (
select 1, timestamp '2019-03-19 00:37:56.030000000 Europe/Paris' from dual
union all
select 2, timestamp '2019-03-19 00:37:56.030000000 Europe/London' from dual
union all
select 3, timestamp '2019-03-19 01:00:00.000000000 Europe/Paris' from dual
union all
select 4, timestamp '2019-03-20 00:37:56.030000000 Europe/Paris' from dual
union all
select 5, timestamp '2019-03-20 00:37:56.030000000 Europe/London' from dual
)
select *
from MY_TABLE
where MY_TIMESTAMP >= timestamp '2019-03-19 00:00:00 Europe/London'
and MY_TIMESTAMP < timestamp '2019-03-20 00:00:00 Europe/London'
/
ID MY_TIMESTAMP
---------- --------------------------------------------------
2 2019-03-19 00:37:56.030000000 EUROPE/LONDON
3 2019-03-19 01:00:00.000000000 EUROPE/PARIS
4 2019-03-20 00:37:56.030000000 EUROPE/PARIS
第一个示例行被排除在外,因为巴黎的 00:37 仍然是伦敦的前一天。第二行和第三行被包括在内,因为它们都在当天的凌晨 - 第三行刚刚进入。第四行被包括在内的原因与第一行被排除在外的原因相同 - 00:37 明天仍然是今天来自伦敦.第五个被排除在外,因为它是在伦敦午夜之后。